I'm building an RN Todo App, which has 2 screens named as HomeScreen and EditScreen and it's look like this HomeScreen EditScreen.
But I don't know how to update from EditScreen using Redux. Please give me some solutions. I really appreciate it.
If you need more details to help me fix this problem, please let me know.
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;
*Update: My app works exactly what I want, I share my code if anyone has the same issue.
CodePudding user response:
you need to change a little bit in your redux setup have a look below
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];
updatedState[index].name = action.payload.name;
},
},
});
export const {addTask, deleteTask,editTask} = taskSlice.actions;
export default taskSlice.reducer;
and from EditScreen.js update a task by sending taskid and task name that you have edited
import {useDispatch} from 'react-redux';
import {editTask} from '....path of taskSlice.js';
...
const dispatch = useDispatch();
const update = () => {
dispatch(editTask({id:'<taskid>',name:'<editted_task_name>'}));
<TouchableOpacity
style={styles.button}
onPress={update}>
<Text style={{color: 'white'}}>Update</Text>
</TouchableOpacity>