React Native Switch切换状态不同步,如何向API传递正确toggle值?
Switch切换时API参数状态滞后的解决办法
问题场景
通过前端Switch组件更新后端布尔值,初始从后端获取状态,用户切换Switch时,向API传递的sharedLocation值总是滞后一步,和当前Switch状态不符。
现有代码:
const toggleSwitch = () => setShareLocation((prevState) => !prevState); const anotherFunction = () => { const shareStatusCheck = { sharedLocation: shareLocation, userID: userID, trusteePhone: trusteePhone, }; axios .post(USER_API + 'modifyShareLocation', shareStatusCheck) .then((res) => { // console.log('SharedLocation status: ', res?.data?.data?.selectedTrustees); }) .catch((err) => { console.log('Error from editShareLocation: ', err); }); }; const callAll = () => { toggleSwitch(); anotherFunction(); }; return( <View style={styles.buttonNormal}> <Text style={styles.buttonTextNormal}>{i18n.t('shareLocation')}</Text> <Switch trackColor={{ false: '#767577', true: '#4E2C70' }} thumbColor={shareLocation ? '#FFFFFF' : '#f4f3f4'} onChange={callAll} value={shareLocation} /> </View> )
原因分析
React的状态更新是异步的,调用setShareLocation后,shareLocation不会立刻更新成新值。所以在callAll里先执行toggleSwitch,紧接着调用anotherFunction时,拿的还是更新前的旧状态,导致参数滞后。
解决方法
这里提供两种简单可行的修改方式:
方式一:直接计算新状态并传递
不用依赖状态变量,直接算出切换后的新值,传给API请求:
// 去掉toggleSwitch函数,直接在callAll里处理 const callAll = () => { const newShareLocation = !shareLocation; // 先更新状态 setShareLocation(newShareLocation); // 用新值构造请求参数 const shareStatusCheck = { sharedLocation: newShareLocation, userID: userID, trusteePhone: trusteePhone, }; // 发起请求 axios .post(USER_API + 'modifyShareLocation', shareStatusCheck) .then((res) => { // 处理返回结果 }) .catch((err) => { console.log('Error from editShareLocation: ', err); // 如果请求失败,把状态切回去,保证前后端一致 setShareLocation(shareLocation); }); };
方式二:用useEffect监听状态变化
把API请求逻辑放到useEffect里,当shareLocation变化时自动触发请求:
// 简化toggleSwitch函数 const toggleSwitch = () => setShareLocation(prev => !prev); // 监听shareLocation变化,自动发起请求 useEffect(() => { const shareStatusCheck = { sharedLocation: shareLocation, userID: userID, trusteePhone: trusteePhone, }; axios .post(USER_API + 'modifyShareLocation', shareStatusCheck) .then((res) => { // 处理返回结果 }) .catch((err) => { console.log('Error from editShareLocation: ', err); // 请求失败回滚状态 setShareLocation(prev => !prev); }); }, [shareLocation, userID, trusteePhone]); // 要把所有相关依赖项加进去 // Switch的onChange直接调用toggleSwitch return( <View style={styles.buttonNormal}> <Text style={styles.buttonTextNormal}>{i18n.t('shareLocation')}</Text> <Switch trackColor={{ false: '#767577', true: '#4E2C70' }} thumbColor={shareLocation ? '#FFFFFF' : '#f4f3f4'} onChange={toggleSwitch} value={shareLocation} /> </View> )
内容的提问来源于stack exchange,提问作者bill2
相关产品推荐
相关产品推荐

