You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在React Native Todo应用中用Redux&Redux Toolkit实现待办项更新

React Native Todo应用Redux实现待办项更新方案

我正在开发一个React Native Todo应用,包含HomeScreen和EditScreen两个页面,但不知道如何在EditScreen中通过Redux实现待办项更新,恳请提供解决方案。以下是我的代码文件:

store.js

import {configureStore} from '@reduxjs/toolkit';
import taskSlice from './taskSlice';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {combineReducers} from 'redux';
import {persistReducer} from 'redux-persist';
import thunk from 'redux-thunk';

const reducers = combineReducers({
  tasks: taskSlice,
});
const persistConfig = {
  key: 'root',
  storage: AsyncStorage,
  whitelist: ['tasks'],
};

const persistedReducer = persistReducer(persistConfig, reducers);

const store = configureStore({
  reducer: persistedReducer,
  devTools: process.env.NODE_ENV !== 'production',
  middleware: [thunk]
});

export default store;

taskSlice.js

import {createSlice, nanoid} from '@reduxjs/toolkit';
export const taskSlice = createSlice({
  name: 'tasks',
  initialState: [],
  reducers: {
    addTask: (state, action) => {
      console.log(nanoid());
      // 'dgPXxUz_6fWIQBD8XmiSy'

      console.log(action.payload);
      const newTask = {
        id: nanoid(),
        name: action.payload.task,
      };
      state.push(newTask);
    },
    deleteTask: (state, action) => {
      console.log('delete', action.payload.id);
      console.log('state', state);
      return state.filter(item => item.id !== action.payload.id);
    },
    editTask: (state, action) => {
      const index = state.findIndex(item => item.id === action.payload.id);
      const updatedState = [...state];
      return void(updatedState[index].name = action.payload.name);
    },
  },
});

export const {addTask, deleteTask, editTask} = taskSlice.actions;

export default taskSlice.reducer;

EditScreen.js

import React, {useState} from 'react';
import {
  View,
  StyleSheet,
  Text,
  TextInput,
  TouchableOpacity,
  Alert,
} from 'react-native';
import {useSelector} from 'react-redux';
import {editTask} from '../redux/taskSlice';
import {useDispatch} from 'react-redux';

const EditScreen = ({route, navigation}) => {
  const {item} = route.params; // get item from HomeScreen
  const todos = useSelector(state => state.tasks);
  console.log('todos', todos);
  const [value, setValue] = useState(item.name);
  const id = item.id;
  const dispatch = useDispatch();

  const update = () => {
    dispatch(editTask({id: id, name: value}));
  };

  const handleSubmit = (): void => {
    if (value.trim().length === 0) {
      Alert.alert('You need to enter a task');
      setValue('');
      return;
    }
  };

  return (
    <View style={{justifyContent: 'center', marginTop: 30}}>
      <Text style={styles.text}> Updating "{item.name}"</Text>

      <View>
        <TextInput
          style={styles.textInput}
          placeholderTextColor="pink"
          placeholder="New Todo..."
          value={value.toString()}
          onChangeText={text => setValue(text)}
        />
        <View style={styles.buttonStyle}>
          {/* Button */}
          <TouchableOpacity
            style={styles.button}
            onPress={() => {
              handleSubmit();
              update();
              navigation.pop(); //use this function to navigate back to the editing note
            }}>
            <Text style={{color: 'white'}}>Update</Text>
          </TouchableOpacity>
          <TouchableOpacity
            style={styles.button}
            onPress={() => navigation.navigate('Home')}>
            <Text style={{color: 'white'}}>Cancel</Text>
          </TouchableOpacity>
        </View>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  text: {
    fontSize: 24,
    color: 'red',
    marginLeft: 10,
  },
  textInput: {
    borderColor: 'black',
    borderWidth: 1,
    padding: 10,
    marginLeft: 20,
    width: '90%',
    borderRadius: 5,
    color: 'black',
  },
  button: {
    backgroundColor: 'black',
    padding: 10,
    margin: 10,
    width: '30%',
    borderRadius: 5,
    alignItems: 'center',
  },
  buttonStyle: {flexDirection: 'row', justifyContent: 'center'},
});

export default EditScreen;

问题修复方案

1. 修正taskSlice.js中的editTask reducer

原写法中return void(...)会返回undefined,导致Redux state被重置,利用Redux Toolkit内置的Immer可以直接修改state:

editTask: (state, action) => {
  const targetTask = state.find(item => item.id === action.payload.id);
  if (targetTask) {
    targetTask.name = action.payload.name;
  }
},

2. 优化EditScreen的提交逻辑

原逻辑中输入为空时仍会执行更新和跳转,修改handleSubmit并调整按钮事件:

const handleSubmit = (): boolean => {
  if (value.trim().length === 0) {
    Alert.alert('You need to enter a task');
    setValue('');
    return false;
  }
  return true;
};

按钮事件修改为:

onPress={() => {
  if (handleSubmit()) {
    update();
    navigation.pop();
  }
}}

更新说明

我的应用已实现预期功能,分享代码供遇到相同问题的开发者参考。

内容的提问来源于stack exchange,提问作者Truong_hp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 14:35:53