我有一个用React Hooks编写的屏幕。
在屏幕上,我在react-navigation标题中有一个自定义按钮。通过按按钮,我需要调用函数updateUser
,该函数使用状态中的值(例如userName
)。
因此,我将updateUser
函数传递给具有navigation.setParams
函数的标头。
在标题中,我从updateUser
叫navigation.state.params
。
第一次按-userName
值正确。但是,如果我随后将在组件内部更改值userName
-当我按下按钮时,函数内部的值将保持不变。
以下是代码示例:
const ProfileScreen = ({navigation}) => {
const [userName, setUserName] = useState('John');
useEffect(() => {
navigation.setParams({
updateUser,
});
}, [])
const updateUser = () => {
console.log('userName', userName);
}
return (...)
};
ProfileScreen.navigationOptions = ({navigation}) => ({
headerRight: () => {
const {params = {}} = navigation.state;
return (
<TouchableOpacity onPress={() => params.updateUser()}>
<Text>Update user</Text>
</TouchableOpacity>
);
},
});
我认为发生这种情况是因为标头不在组件范围内,并且不会获得更新的状态值。此外,React还具有一条规则,该规则规定不要在React函数外部调用钩子。
有没有适当的方法来解决?如果没有,什么解决方法?
答案 0 :(得分:2)
我的解决方法#1 是要再使用一个useState
,它可以一直跟踪是否按下了“更新”按钮。
因此,在标题中,当按下按钮时,我们将isUpdateButtonPressed
设置为true。然后,在组件中,我们监视该更改,如果更改了,则将其称为updateUser
。这样,状态在updateUser
函数内部是正确的。
const ProfileScreen = ({navigation}) => {
const [userName, setUserName] = useState('John');
const [isUpdateButtonPressed, setIsUpdateButtonPressed] = useState(false);
useEffect(() => {
navigation.setParams({
setIsUpdateButtonPressed,
});
}, [])
useEffect(() => {
if (isUpdateButtonPressed) {
updateUser();
setIsUpdateButtonPressed(false);
}
}, [isUpdateButtonPressed]);
const updateUser = () => {
console.log('userName', userName);
}
};
ProfileScreen.navigationOptions = ({navigation}) => ({
headerRight: () => {
const {params = {}} = navigation.state;
return (
<TouchableOpacity onPress={() => params.setIsUpdateButtonPressed(true)}>
<Text>Update user</Text>
</TouchableOpacity>
);
},
});
我的解决方案#2 是使用useEffect
来监视updateUser
函数中使用的所有变量,并使用更新后的navigation.setParams
函数调用updateUser
每当这些变量更改时:
useEffect(() => {
navigation.setParams({
updateUser,
});
}, [userName])
尽管解决方案#2在代码上更简洁一些,但我个人更喜欢解决方案#1,因为第二种解决方案可能会导致不明显的错误,以防万一我们错过了在updateUser
函数中使用的变量的添加,使用效果数组。