Feature |
useState
|
useReducer
|
---|---|---|
Complexity | Ideal for simple state logic | Suitable for complex state logic |
State Updates | Directly set state via updater | Use a reducer function to determine state changes |
Structure | Single piece of state | State + Dispatch + Reducer Function |
Scalability | Can become messy with multiple states | Organizes updates into a single function |
import React, { render, useState } from "react";
const CounterWithState = () => {
const [count, setCount] = useState(0);
const [word, setWord] = useState("");
function changeHandler(e) {
setWord(e.currentTarget.value);
setCount(e.currentTarget.value.length);
}
function del() {
if (word.length) {
setWord(word.slice(0, -1));
setCount(count - 1);
}
}
function reset() {
setWord("");
setCount(0)
}
return (
<div>
<h1>Counter with useState</h1>
<p>Letters: {count}</p>
<input value={word} onChange={changeHandler} />
<button onClick={del}>Delete</button>
<button onClick={reset}>Reset</button>
</div>
);
};
render(<CounterWithState />)
body {
padding: 16px;
font-size: 24px;
}
h1 {
font-size: 32px;
}
import React, { render, useReducer } from "react";
type State = {
word: string,
count: number
}
type Action =
| { type: 'WORD', value: string }
| { type: 'DELETE' }
| { type: 'RESET' }
const reducer = (state: State, action: Action) => {
switch (action.type) {
case "WORD":
return {
count: action.value.length,
word: action.value
};
case "DELETE":
return state.word.length
? {
count: state.count - 1,
word: state.word.slice(0, -1)
}
: state;
case "RESET":
return { word: '', count: 0 };
default:
throw new Error("Action not handled");
}
};
const CounterWithReducer = () => {
const [state, dispatch] = useReducer(
reducer,
{ count: 0, word: "" }
);
return (
<div>
<h1>Counter with useState</h1>
<p>Letters: {state.count}</p>
<input
value={state.word}
onChange={(e) => {
dispatch({
type: 'WORD',
value: e.currentTarget.value
})
}}
/>
<button
onClick={() => dispatch({ type: 'DELETE' })}>
Delete
</button>
<button
onClick={() => dispatch({ type: 'RESET' })}>
Reset
</button>
</div>
);
};
render(<CounterWithReducer />)
body {
padding: 16px;
font-size: 24px;
}
h1 {
font-size: 32px;
}