Answer the question
In order to leave comments, you need to log in
Reducer is called 2 times in useReducer?
I have a simple todo application.
The problem is: the reducer is called 2 times. Each todo item has a checkbox, when you click on it, the checked value changes to the opposite, but due to the fact that this happens 2 times, it remains the same as it was. Everything worked fine before useReducer .
Tried to call dispatch.bind(null,action) didn't help, replaced onChange with onClick didn't work
. Action 'add' and 'del' work, they are also called 2 times but everything is displayed correctly in the DOM.
Seravno I can't understand why the reducer is called 2 times.
Doki read the video, watched it, copied the counter from the offsite. There, too, the reducer was called op 2 times
. I use only useReducer , without redux
App.js
import React, { useState, useEffect, useReducer } from "react";
import TodoList from "./TodoList";
export const ContextApp = React.createContext();
const reducer =(state,action)=>{
console.log('reducer')
switch (action.type) {
case 'add':
console.log('add')
return [
...state,
{
id: new Date()+Math.random(),
title: action.title,
desc: action.text,
checked: false,
}
]
case 'checked':
return state.map(item=>{
if(item.id === action.id){
item.checked = !item.checked;
}
return item;
})
case 'del':
return state.filter(item=>item.id!==action.id)
default:
return state
}
}
function App() {
const [state, dispatch] = useReducer(reducer, [])
const [todoValue, setValue] = useState({
input: "",
text: "",
});
useEffect(()=>{
console.log(state);
},[state])
return (
<ContextApp.Provider value={{dispatch}}>
<div className="App">
<div className="create_box">
<input
type="text"
id="input"
onChange={({ target }) => {
setValue({
[target.id]: target.value,
text: todoValue.text,
});
}}
/>
<textarea
id="text"
onChange={({ target }) => {
setValue({
input: todoValue.input,
[target.id]: target.value,
});
}}
></textarea>
<button onClick={()=>dispatch({
type:'add',
title:todoValue.input,
text:todoValue.text
})}> add </button>
</div>
<div className="todo_list" >
<TodoList todo={state} />
</div>
</div>
</ContextApp.Provider>
);
}
export default App;
import React, { useContext } from 'react';
import { ContextApp } from './App';
const TodoItem = ({title,desc,checked,id}) => {
const {dispatch} = useContext(ContextApp)
return (
<div className={!checked?"todo_item":"todo_item check"}>
<h2>{title}</h2>
<p className="desc">{desc} </p>
<input type="checkBox" checked={checked} onChange={()=>{dispatch({
type:'checked',
id
})}} />
<button onClick={()=>{
dispatch({
type:'del',
id
})
}}>del</button>
</div>
);
}
export default TodoItem;
import React from 'react'
import TodoItem from './TodoItem'
export default function TodoList({todo}) {
return todo.map(item=> <TodoItem key={item.id} {...item} />)
};
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question