React Native+Redux问题:NaN报错及FlatList展示待办项
React Native + Redux 待办应用问题修复方案
核心问题修复说明
1. NaN值问题解决
- Action传参错误:原代码中
addToList/removeFromList硬编码字符串"newToDo",未传递用户真实输入内容,导致Reducer处理无效值 - Reducer逻辑错误:原代码对数组执行减法操作,且强制将无效字符串转为数字,直接产生NaN;改为通过数组添加/过滤操作维护待办项集合
- 输入框未绑定状态:原TextInput无
onChangeText回调,用户输入无法更新,新增本地状态维护输入值 - State映射错误:原
mapStateToProps错误映射字段,改为正确关联store中的待办项数组
2. FlatList展示问题解决
- 数据源错误:原FlatList误用action函数作为
data,改为使用store中的待办项数组 - 渲染函数缺失:新增
renderTodoItem函数处理单个待办项的渲染逻辑 - Key提取逻辑修正:使用索引作为key(若待办项有唯一标识可替换为对应字段)
修改后的完整代码
1. TaskList组件
import { Text, View, Button, StyleSheet, TextInput, SafeAreaView, FlatList, } from 'react-native'; import { useState } from 'react'; import { connect } from 'react-redux'; import { addToList, removeFromList, reset } from '../redux/actions/index'; const TaskList = ({ todoList, history, addToList, removeFromList, reset }) => { // 本地维护输入框状态 const [inputValue, setInputValue] = useState(''); const renderTodoItem = ({ item }) => ( <Text style={{ borderWidth: 1, borderColor: 'gray', borderRadius: 5, margin: 10, padding: 5, }}> {item} </Text> ); return ( <View> <SafeAreaView> <TextInput style={styles.input} value={inputValue} placeholder="Enter Value Here" onChangeText={setInputValue} /> <View style={styles.button}> <Button title="Add Values to List" onPress={() => { if (inputValue.trim()) { addToList(inputValue); setInputValue(''); } }} /> </View> <View style={styles.button}> <Button title="Remove From List" onPress={() => { if (inputValue.trim()) { removeFromList(inputValue); setInputValue(''); } }} /> </View> <View style={styles.button}> <Button title="Reset" onPress={reset} /> </View> <Text style={styles.sectionTitle}>操作历史:</Text> {history.map((item, index) => ( <Text key={index} style={{ borderWidth: 1, borderColor: 'gray', borderRadius: 5, margin: 10, padding: 5, }}> {item} </Text> ))} <Text style={styles.sectionTitle}>待办列表:</Text> <FlatList data={todoList} renderItem={renderTodoItem} keyExtractor={(item, index) => index.toString()} style={{ marginBottom: 20 }} /> </SafeAreaView> </View> ); }; const styles = StyleSheet.create({ input: { padding: 5, textAlign: 'center', borderWidth: StyleSheet.hairlineWidth * 2, borderColor: 'gray', borderStyle: 'solid', borderRadius: StyleSheet.hairlineWidth * 10, marginTop: StyleSheet.hairlineWidth * 20, marginBottom: StyleSheet.hairlineWidth * 20, }, button: { margin: 5, }, sectionTitle: { fontSize: 16, fontWeight: 'bold', marginLeft: 10, marginTop: 15, }, }); const mapStateToProps = (store) => ({ todoList: store.listReducer.list, history: store.listReducer.history, }); const mapDispatchToProps = { addToList, removeFromList, reset }; export default connect(mapStateToProps, mapDispatchToProps)(TaskList);
2. Redux Action
import { ADD_TO_LIST, REMOVE_FROM_LIST, RESET_LIST } from '../actionTypes/index'; export const addToList = (todoText) => { return { type: ADD_TO_LIST, payload: { toDo: todoText, }, }; }; export const removeFromList = (todoText) => { return { type: REMOVE_FROM_LIST, payload: { toDo: todoText, }, }; }; export const reset = () => { return { type: RESET_LIST, }; };
3. List Reducer
import { ADD_TO_LIST, REMOVE_FROM_LIST, RESET_LIST, } from '../actionTypes/index'; const initialState = { history: [], list: [], }; export default function listReducer(state = initialState, action) { switch (action.type) { case ADD_TO_LIST: return { ...state, list: [...state.list, action.payload.toDo], history: [...state.history, `添加: ${action.payload.toDo}`], }; case REMOVE_FROM_LIST: return { ...state, list: state.list.filter(item => item !== action.payload.toDo), history: [...state.history, `移除: ${action.payload.toDo}`], }; case RESET_LIST: return { ...state, list: [], history: [] }; default: return state; } }
4. 主App组件
import { Provider } from 'react-redux'; import TaskList from './TaskList/index'; import store from './redux/store'; export default function App() { return ( <Provider store={store}> <TaskList /> </Provider> ); }
内容的提问来源于stack exchange,提问作者DevSteph
相关产品推荐
相关产品推荐

