React Native开发中向数组push元素时旧数据丢失问题
问题根因
- 你的
chatHistory变量直接声明在函数组件的顶层作用域,React 函数组件每次状态更新触发重渲染时,整个组件函数都会重新执行一遍。你修改输入框内容时会更新text状态触发组件重渲染,let chatHistory = []会反复执行,每次都创建一个全新的空数组,之前存入的内容自然就丢失了。
修复方案
你可以根据你的使用场景二选一:
方案1:用useState存储聊天历史(推荐,需要渲染历史时必选)
useState托管的状态会被 React 持久化存储,不会随组件重渲染重置,更新状态还会自动触发组件刷新,如果你后续需要把聊天历史展示在页面上,选这个方案:
const [text, onChangeText] = React.useState('Useless Text'); // 用useState存聊天历史 const [chatHistory, setChatHistory] = React.useState([]); function logHistory(text) { // 用回调写法更新数组,避免闭包导致的旧值问题 setChatHistory(prevHistory => [...prevHistory, text]); // 注意setChatHistory是异步的,要打印最新值可以直接输出拼接后的新数组 const newHistory = [...chatHistory, text]; console.log(newHistory); } return ( <View style={styles.container}> <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <TextInput style={styles.input} onChangeText={onChangeText} value={text} /> <Button title={'Ask the computer...'} onPress={() => logHistory(text)} /> </View> </View> );
方案2:用useRef存储聊天历史(仅存日志不需要渲染时用)
如果你只是需要存储历史做日志打印,不需要把内容渲染到页面上,可以用useRef,它的current属性值不会随组件重渲染重置,修改它也不会触发多余的重渲染,性能更优:
const [text, onChangeText] = React.useState('Useless Text'); // 用useRef存聊天历史 const chatHistoryRef = React.useRef([]); function logHistory(text) { chatHistoryRef.current.push(text); console.log(chatHistoryRef.current); } return ( <View style={styles.container}> <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <TextInput style={styles.input} onChangeText={onChangeText} value={text} /> <Button title={'Ask the computer...'} onPress={() => logHistory(text)} /> </View> </View> );
内容的提问来源于stack exchange,提问作者alfvar
相关产品推荐
相关产品推荐

