React Native状态切换问题:API请求后如何返回初始界面状态
问题
我的项目包含两种状态:
- 状态一:用户从相册选择图片并点击选择按钮
- 状态二:用户点击按钮发起API请求
目标是通过对应按钮切换状态,目前可从状态一切换到状态二,但无法从状态二切回状态一。相关代码如下:
App.js
const pickImageAsync = async () => { let result = await ImagePicker.launchImageLibraryAsync({ allowsEditing: true, quality: 1, }); if (!result.canceled) { setSelectedImage(result.assets[0].uri); setShouldShow(!shouldShow); } else { alert("You need to choose an image."); } }; return ( <View style={styles.container}> {shouldShow ? ( <View style={styles.footerContainer}> <Button theme="primary" label="Escolher imagem" onPress={pickImageAsync} /> </View> ) : null} {!shouldShow ? ( <View style={styles.footerContainer} > <PostRequest /> </View> ) : null} </View> );
PostRequest.js
const [shouldShow, setShouldShow] = useState(true); const postExample = async () => { try { await fetch( 'https://reqres.in/api/posts', requestOptions) .then(response => { response.json() .then(data => { Alert.alert("Post created at : ", data.createdAt); }); }) } catch (error) { console.error(error); } } return ( <View style={styles.btn}> <Button onPress={() => {postExample; setShouldShow(!shouldShow)}} > Post</Button> </View> ) }
我尝试在按钮点击时执行两个函数,但由于shouldShow并非全局变量,该方法无效,求优雅的解决方案。
解决方案
核心问题是状态被重复声明:App.js和PostRequest.js各维护了一个独立的shouldShow状态,PostRequest里修改的只是自身的局部状态,不会影响App.js的状态判断。
解决思路是将状态统一提升到父组件(App.js),通过props把状态修改方法传递给子组件(PostRequest),具体步骤如下:
1. 移除PostRequest的局部状态
删除PostRequest中独立的状态声明:const [shouldShow, setShouldShow] = useState(true);
2. 给PostRequest传递状态切换回调
在App.js渲染PostRequest时,将父组件的setShouldShow封装成回调函数传入:
{!shouldShow ? ( <View style={styles.footerContainer} > <PostRequest onToggleShow={() => setShouldShow(!shouldShow)} /> </View> ) : null}
3. 修改PostRequest的按钮逻辑
在PostRequest中接收onToggleShow props,完成API请求后调用该回调切换状态,同时修正原代码中未执行postExample的问题:
const PostRequest = ({ onToggleShow }) => { const postExample = async () => { try { const response = await fetch('https://reqres.in/api/posts', requestOptions); const data = await response.json(); Alert.alert("Post created at : ", data.createdAt); onToggleShow(); // 请求完成后触发状态切换 } catch (error) { console.error(error); } } return ( <View style={styles.btn}> <Button onPress={postExample} > Post</Button> </View> ) }
注:将嵌套的.then改为await写法,代码更简洁易读。
4. 可选优化:简化App.js条件渲染
合并两个条件渲染分支,让代码更紧凑:
return ( <View style={styles.container}> <View style={styles.footerContainer}> {shouldShow ? ( <Button theme="primary" label="Escolher imagem" onPress={pickImageAsync} /> ) : ( <PostRequest onToggleShow={() => setShouldShow(!shouldShow)} /> )} </View> </View> );
内容的提问来源于stack exchange,提问作者BodeTech
相关产品推荐
相关产品推荐

