У меня есть простейшие приложение todo .
Проблема во в чем: reducer вызывается 2 раза . В каждом todo item есть чекбокс по клику на него значение checked меняться на противоположное но из-за того что это происходит 2 раза , оно остается таким же как и было . До useReducer все работало хорошо .
Пробовал вызывать dispatch.bind(null,action) не помогло , заменял onChange на onClick нечего не дало
Action 'add' и 'del' работаю , тоже вызываются по 2 раза но в DOM все верно отображается .
Серавно не могу понять почему вызывается по 2 раза reducer .
Доки читал видео смотрел , скопировал счечик с оф.сайта там тоже reducer вызывался оп 2 раза
Использую только useReducer , без 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;
TodoItem.js // вот здесь чекбокс
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} />)
};
На сайте уже есть похожий вопрос это я его задавал но правильного ответа не было