Ist es notwendig, den Spread-Operator in useReducer zu verwenden?
BEARBEITEN: Nachdem ich Brians Antwort überprüft hatte, stellte ich fest, dass das Entfernen selbst im zweiten Beispiel ...statedas gleiche Verhalten wie im ersten Beispiel verursachen würde. Daher war diese Frage falsch zu stellen. Ich bin mir nicht sicher, warum ich das falsche Verhalten gesehen und mich für etwaige Unannehmlichkeiten entschuldigt habe. Brians Antwort ist eine gute Erklärung für die Verwendung.
Vergleichen Sie die folgenden 2 Code-Schnipsel. Sie machen dasselbe, indem sie beide 2 Zustände gleichzeitig mit einem aktualisieren initialState, außer einer verwendet useStateund der andere verwendet useReducer:
useState
const {useState} = React;
const initialState = {
name: 'John',
age: 20
};
const Example = () => {
const [state, setState] = useState(initialState);
const handleName = () => {
setState({...state, name: 'Tom'});
}
const handleAge = () => {
setState({...state, age: 30});
}
return (
<div>
<p>{state.name}</p>
<p>{state.age}</p>
<button onClick={handleName}>
Click to change name
</button>
<button onClick={handleAge}>
Click to change age
</button>
</div>
);
};
ReactDOM.render(
<Example />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
useReducer
const {useReducer} = React;
const initialState = {
name: 'Tom',
age: 30
}
const reducer = (state, action) => {
switch (action.type) {
case 'name':
return {
...state,
name: 'John'
}
case 'age':
return {
...state,
age: 25
}
default:
return state
}
}
const Example = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Name: {state.name}</p>
<p>Age: {state.age}</p>
<button onClick={() => dispatch({ type: 'name' })}>Click to update name</button>
<button onClick={() => dispatch({ type: 'age' })}>Click to update age</button>
</div>
)
};
ReactDOM.render(
<Example />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Beim Entfernen ...stateim ersten Beispiel wird der Status auf ein einzelnes Schlüssel / Wert-Paar gesetzt, sodass dies nicht mehr funktioniert. Ich hatte erwartet, dass im zweiten Beispiel dasselbe passieren würde, aber das tat es nicht. Das zweite Beispiel funktioniert gut, wenn der Spread-Operator entfernt wurde.
Ich habe 3 Fragen zum 2. Beispiel:
- Was nützt der Spread-Operator?
- Warum funktioniert es nach dem Entfernen der Spread-Operatoren immer noch?
- Wenn es ohne den Spread-Operator gut funktioniert, bedeutet dies, dass der Spread-Operator im zweiten Beispiel nicht benötigt wird?
Antworten
Ich verstehe , dass dies eine sehr ähnliche Frage zu diesem , aber ich gebe eine Antwort sowieso hoffentlich zukünftige Leser davon ab, falsche Informationen zu verhindern.
Weder useStatenoch useReducerirgendeine Verschmelzung von vorherigen Werten. Die Beibehaltung früherer Statuswerte liegt in Ihrer Verantwortung während der Statusaktualisierung (entweder im setStateAufruf oder in der Definition der Reduzierungsfunktion).
Sie können dies deutlich im geänderten Code unten sehen. Alles, was ich geändert habe, ist das Entfernen ...statevon jedem Schaltergehäuse.
const {useReducer} = React;
const initialState = {
name: 'Tom',
age: 30
}
const reducer = (state, action) => {
switch (action.type) {
case 'name':
return {
name: 'John'
}
case 'age':
return {
age: 25
}
default:
return state
}
}
const Example = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Name: {state.name}</p>
<p>Age: {state.age}</p>
<button onClick={() => dispatch({ type: 'name' })}>Click to update name</button>
<button onClick={() => dispatch({ type: 'age' })}>Click to update age</button>
</div>
)
};
ReactDOM.render(
<Example />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Der Grund, warum der Spread-Operator für diesen Zweck so häufig verwendet wird, ist die am wenigsten langwierige Methode, um alle unveränderten Werte in das neue Objekt einzufügen.