我有一个用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函数之外调用钩子。
有没有适当的解决方法?如果没有,什么解决方法?
我的[[解决方法#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
函数中添加某些变量以使用useEffect数组的情况。