首页 > 解决方案 > 将 useState 更新函数传递给子进程会导致未定义的函数错误

问题描述

使用 expo 和 react-native 我创建了一个名为MainStateScreenthis screen 的屏幕,它基本上有两个直接的子级,称为OptionsComponentand NavigationButtonOptionsComponent有多个子元素,在修改时更新 的状态,MainStateScreen以便我们可以将其作为道具传递给带有NavigationButton. 至少它应该是这样工作的。

相反,当我尝试修改OptionsComponent' 的子级并使用MainStateScreen' 更新功能时,我收到以下错误。

这是我的组件组成的伪代码:

MainStateScreen.js

const defaultOptionsObject = [
    {
        name: '',
        value: 1,
        count: 0,
    },
    {
        name: '',
        value: 8,
        count: 0,
    },
    {
        name: '',
        value: 20,
        count: 0,
    },
    {
        name: '',
        value: 25,
        count: 0,
    },
    {
        name: '',
        value: 30,
        count: 0,
    },
    {
        name: '',
        value: 32,
        count: 0,
    },
    {
        name: '',
        value: 100,
        count: 0,
    },
]

const MainStateScreen = () => {
    const [options, setOptions] = useState(defaultOptionsObject)

    return (
        <View>
            <ScrollView>
                <OptionsComponent options={options} setOptions={setOptions} />
            </ScrollView>
            <NavigationButton onPress={() => navigation.push('OtherScreen', { options })} />
        </View>
    )
}

选项组件.js

const SingleOptionComponent = ({ index, option, options, setOptions }) => {
    const [stateOption, setStateOption] = useState({ ...option })

    const updateCount = val => {
        const tempOption = { ...stateOption }
        if (val) {
            tempOption.count += 1
        } else if (tempOption.count !== 0) {
            tempOption.count -= 1
        }
        setStateOption(tempOption)
    }

    useEffect(() => {
        const tempOptions = [ ...options ]
        tempOptions[index] = { ...stateOption }
        setOptions(tempOptions) // Commenting this out removes the error.
    }, [stateOption])

    const AddSubtractButton = () => {
        return (
            <View>
                <TouchableHighlight onPress={() => updateCount(true)}>
                    <Text>Add</Text>
                </TouchableHighlight>
                <TouchableHighlight onPress={() => updateCount(false)}>
                    <Text>Subtract</Text>
                </TouchableHighlight>
            </View>
        )
    }

    return (
        <ListItem rightElement={AddSubtractButton} />
    )
}

const OptionsComponent = ({ options, setOptions }) => {
    return (
        <View>
            {options.map((option, index) => {
                return (
                    <SingleOptionComponent
                        key={`${option?.value}-${index}`}
                        index={index}
                        option={option}
                        options={options}
                        setOptions={setOptions}
                    />
                )
            })}
        <View/>
    )
}

确切的错误是:

TypeError: undefined is not a function (near '...options.map...')

This error is located at:
    in OptionsComponent (at MainStateScreen.js)

但是,当我在of中console.logsetOptions功能时,会在控制台中打印。useEffectSingleOptionComponentFunction setOptions

如果我从内部删除setOptions(tempOptions)调用,错误就会消失,但我需要类似的东西来完成传递给父级并传递给.useEffectSingleOptionComponentNavigationButton

我可能做错了什么?

标签: androidreact-nativeexpo

解决方案


我建议的几件事可以解决问题,而无需在我的机器上重新创建它。尝试添加setOptionsuseEffect依赖数组。也许由于某种原因,它没有得到更新的 setOptions ,因为它被传递给了孙子组件。您还应该将其传递options给它,因为您的效果取决于该值何时更改。

如果这不起作用,请尝试使用扩展运算符setOptions({ ... tempOptions})

如果这不起作用,我建议在最上面的组件中处理 setOptions ,而是将回调传递给孙子而不是setOptions函数。该回调并option在父级中按下,然后根据它适当地更新它option._id(我会为每个选项提供一个唯一的 _id 而不是动态计算它只是为了能够执行上述操作。)。也使代码更容易理解发生了什么,因为父级将处理它自己需要的状态并适当地设置它。


推荐阅读