Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Вивчайте Modifying State by Dispatching Actions | Redux in Practice
Introduction to Redux

book
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:

js
import { 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 reducer
export 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:

js
import 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:

js
import 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:

js
import 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:

js
const 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:

js
const 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:

js
import 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 here
dispatch(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:

question mark

How can we send additional data with dispatched actions?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 3. Розділ 8

Запитати АІ

expand
ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

We use cookies to make your experience better!
some-alt