React Native中RNFS读取JSON后useState未更新,请求帮助
React Native使用RNFS读取JSON文件无法更新useState的问题
我尝试读取路径下的JSON文件并将内容存入useState变量,但点击按钮打印时始终输出空对象,无法获取文件内容。
mydata.json内容
{ "key":"value" }
我的代码
import React, { useState } from 'react'; import { View,Button,Text, StyleSheet } from 'react-native'; import RNFS from "react-native-fs"; function App({route}){ const [jsonData, setJsonData] = useState({}); try { RNFS.readFile("mydata.json","utf-8", function(err,data){ const jsonDataObject = JSON.parse(data.toString()); setJsonData(jsonDataObject); }); } catch (error) { console.error(error); } return ( <View style={styles.content}> <Text> hello </Text> <Button onPress={()=>(console.log("your json : ",jsonData))} title='print' /> </View> ); } const styles = StyleSheet.create( { content:{ flex:1, alignItems:"center", justifyContent:"center" } } ) export default App;
实际输出
LOG : {} LOG : {} LOG : {}
预期输出
LOG : {"key":"value"} LOG : {"key":"value"} LOG : {"key":"value"}
问题原因及解决方法
1. 文件路径错误
RNFS的readFile默认读取文档目录(DocumentDirectoryPath),直接写"mydata.json"会找不到文件,需根据文件实际位置指定路径:
- 若文件是打包在APP安装包内的资源文件,用
RNFS.MainBundlePath拼接:const filePath = `${RNFS.MainBundlePath}/mydata.json`; - 若文件在用户文档目录下,用
RNFS.DocumentDirectoryPath拼接:const filePath = `${RNFS.DocumentDirectoryPath}/mydata.json`;
2. 异步回调的错误无法被外层try/catch捕获
RNFS.readFile的回调是异步执行的,外层try/catch无法捕获内部错误,需改用Promise风格调用并在内部处理错误。
3. 未在正确的生命周期钩子中执行异步操作
组件挂载时直接执行异步读取,应放在useEffect中确保只执行一次,避免重复触发。
修改后的代码
import React, { useState, useEffect } from 'react'; import { View, Button, Text, StyleSheet } from 'react-native'; import RNFS from "react-native-fs"; function App({ route }) { const [jsonData, setJsonData] = useState({}); useEffect(() => { const readJsonFile = async () => { try { // 根据文件实际位置修改路径,此处以安装包内文件为例 const filePath = `${RNFS.MainBundlePath}/mydata.json`; const data = await RNFS.readFile(filePath, "utf-8"); const jsonDataObject = JSON.parse(data); setJsonData(jsonDataObject); } catch (error) { console.error("读取文件失败:", error); } }; readJsonFile(); }, []); return ( <View style={styles.content}> <Text>hello</Text> <Button onPress={() => console.log("your json : ", jsonData)} title='print' /> </View> ); } const styles = StyleSheet.create({ content: { flex: 1, alignItems: "center", justifyContent: "center" } }); export default App;
内容的提问来源于stack exchange,提问作者islam abdelmoumen
相关产品推荐
相关产品推荐

