Aquí está mi componente de reacción y mi función reductora:
const testReducer = (state) => { const newState = {...state} newState.counts[0] += 1 return newState } function App() { const [countState, dispatchCount] = useReducer(testReducer, {counts: [0]}) return ( <div className="App"> <h1>{countState.counts[0]}</h1> <button onClick={dispatchCount}>up</button> </div> ); }
Cuando se hace clic en el botón y se ejecuta el reductor, espero que el recuento que se muestra en el H1 aumente en uno. Esto sucede cuando se hace clic en el botón por primera vez, pero cada clic posterior lo incrementa en 2.
Esto sucede sin importar en qué se inicialice el conteo. Si el valor que estoy incrementando no está en una matriz, funciona normalmente.
¿Puede alguien decirme por qué está pasando esto?
newState.counts[0] = += 1
no es una sintaxis válida. Suponiendo que quiso decir newState.counts[0] += 1
, entonces está mutando el objeto de estado.
const testReducer = (state) => { const newState = {...state} newState.counts[0] += 1 // <-- mutates newState.counts!! return newState }
Con toda probabilidad, esta mutación se expone en su aplicación al procesarse dentro de un componente React.StrictMode
.
StrictMode: detección de efectos secundarios inesperados
El modo estricto no puede detectar automáticamente los efectos secundarios, pero puede ayudarlo a detectarlos haciéndolos un poco más deterministas. Esto se hace mediante una doble invocación intencional de las siguientes funciones:
- Métodos
constructor
de componentes de clase,render
yshouldComponentUpdate
- Componente de clase método estático
getDerivedStateFromProps
- Cuerpos de componentes de función
- Funciones de actualización de estado (el primer argumento de
setState
)- Funciones pasadas a
useState
,useMemo
ouseReducer
<-- esto
A pesar de que está copiando un estado superficial, aún necesita devolver una nueva referencia de matriz de counts
.
const testReducer = (state) => { const newState = { ...state, counts: [state.counts[0] + 1] }; return newState; };