Modifying State by Dispatching Actions
We learned how to access data from the application state, now we want to make changes. For modifying the application state, we dispatch actions.
Recall that the createSlice
function automatically generates the action creators. Currently, our todoSlice
file looks like this:
js99123456789101112131415161718192021import { createSlice } from '@reduxjs/toolkit'export const todosSlice = createSlice({name: 'todo',initialState: ['Finish the application', 'abc', 'test'],reducers: {addTodo: (state, action) => {const item = action.payload;if(item != '') {state.push(item);}}}});// We can export the returned action(s)export const { addTodo } = todosSlice.actions;// We can export the reducerexport default todosSlice.reducer;// 'todos' is the slice of the state we created in 'store.js'export const selectTodos = (state) => state.todos;
We will use the addTodo
action creator in index.js
to add new items to the Todo list. Currently, the index.js
file looks like this:
js9912345678910111213141516171819202122232425262728293031import React from 'react';import { createRoot } from 'react-dom/client';import { Provider, useSelector } from 'react-redux';import { store } from './app/store';import { selectTodos } from './todosSlice';function App(props) {const todos = useSelector(selectTodos);return (<div><h1>Todo Application Using Redux</h1><form><ul>{todos.map((item, index) => <li key={index}>{item}</li>)}</ul><input></input><button>Add</button></form></div>);}createRoot(document.getElementById('root')).render(<React.StrictMode><Provider store={store}><App /></Provider></React.StrictMode>);
We will import addTodo
from todosSlice
, useDispatch
from react-redux
, and useState
from react
.
useDispatch
will allow us to dispatch actions, while useState
is for creating local states which we don’t want to store in the global application state.
Out imports should now look like this:
js912345import React, { useState } from 'react';import { createRoot } from 'react-dom/client';import { Provider, useSelector, useDispatch } from 'react-redux';import { store } from './app/store';import { selectTodos, addTodo } from './todosSlice';
We will create a local state variable called text
, representing the user's input along with two functions, one for handling the input and one for handling the submission. The code in index.js
should now look like this:
js99123456789101112131415161718192021222324252627282930313233343536import React, { useState } from 'react';import { createRoot } from 'react-dom/client';import { Provider, useSelector, useDispatch } from 'react-redux';import { store } from './app/store';import { selectTodos, addTodo } from './todosSlice';function App(props) {const todos = useSelector(selectTodos);const [ text, setText ] = useState('');const handleChange = (e) => {setText(e.target.value);};const handleSubmit = (e) => {e.preventDefault();// Update the state here};return (<div><h1>Todo Application Using Redux</h1><form><ul>{todos.map((item, index) => <li key={index}>{item}</li>)}</ul><input value={text} onChange={handleChange} /><button onClick={handleSubmit}>Add</button></form></div>);}createRoot(document.getElementById('root')).render(<React.StrictMode>
The application will look something like this:
However, the Add
button will have no effect since we have yet to write code. Note that the handleSubmit
function is pretty much empty.
We will declare a new constant in the App
component and assign a useDispatch
call to it:
jsconst dispatch = useDispatch();
We will then use this const function to dispatch the addTodo
function in the handleSubmit
function, passing the argument text
in it. We will also clear the text
afterward:
js912345const handleSubmit = (e) => {e.preventDefault();dispatch(addTodo(text));setText('');};
Note that we can pass extra data with the action by passing an argument to the action creator. In this case, we directly passed a string text
. For more data, we can pass an object containing key-value pairs and access it using the payload
from todosSlice
. The final code will look like this:
js99123456789101112131415161718192021222324252627282930313233343536import React, { useState } from 'react';import { createRoot } from 'react-dom/client';import { Provider, useSelector, useDispatch } from 'react-redux';import { store } from './app/store';import { selectTodos, addTodo } from './todosSlice';function App(props) {const dispatch = useDispatch();const todos = useSelector(selectTodos);const [ text, setText ] = useState('');const handleChange = (e) => {setText(e.target.value);};const handleSubmit = (e) => {e.preventDefault();// Update the state heredispatch(addTodo(text));setText('');};return (<div><h1>Todo Application Using Redux</h1><form><ul>{todos.map((item, index) => <li key={index}>{item}</li>)}</ul><input value={text} onChange={handleChange} /><button onClick={handleSubmit}>Add</button></form></div>);}
Now we should be able to add new items to the Todo list:
Дякуємо за ваш відгук!
Запитати АІ
Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат