使用提供的适当 API。
不是
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count — 1);
反而
const [count, setCount] = useState(0);
const increment = () => setCount((prevCount) => prevCount + 1);
const decrement = () => setCount((prevCount) => prevCount — 1);
setState 有两种类型的参数。
直接接收下一个状态作为参数的接口。
setState(newState);
一个接口,它接受一个参数,从以前的状态计算一个新的状态。
setState((prev) => createNewStateFromPrevState(prev));
计数器应用程序增量在 useState 介绍性文章的主题中经常作为示例出现,意思是“函数将前一个计数加 1”。
因此将setCount ((prev) => prev + 1) 应用于第二个函数接口是合适的。递减也是如此。
出现问题的情况
您可能认为第一种编码方式正确
碰巧样本工作正常,并且可能存在难以发现的错误。
例如,假设您将 useCounter
模块化为一个实用程序函数,您可以在应用程序的任何位置使用它。
export const useCounter = (init: number = 0) => {
const [count, setCount] = useState(init);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count — 1);
return { count, increment, decrement };
};
useCounter 的一个用户,发现 increment 和 decrement 不接收参数,只能操作一个差值,想应用它并改变它两个, 他只能调用两次
import { useCounter } from “./useCounter”;
export default function App() {
const { count, increment, decrement } = useCounter(10);
const incrementDouble = () => {
increment();
increment();
};
const decrementDouble = () => {
decrement();
decrement();
}; return (
<div className=”App”>
<h1>Count: {count}</h1>
<button onClick={incrementDouble}>+2</button>
<button onClick={decrementDouble}>-2</button>
</div>
);
}
上面的这段代码不能正常工作。如果您单击 +2 按钮,似乎会添加 2 但只添加了 +1
如果按钮被点击一次,增量(或减量)被调用两次,所以它应该改变两次。为什么?
因为它只是一遍又一遍地将相同的值传递给 setCount。
count 只是一个常数,而不是一个变量值
export default function App() {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
return (
<div className="App">
<h1>Count: {count}</h1>
<button onClick={increment}>+1</button>
<button onClick={decrement}>-1</button>
</div>
);
}
当count === 20时,组件的内容写成如下
export default function App() {
const [20, setCount] = useState(0);
const increment = () => setCount(20 + 1);
const decrement = () => setCount(20 - 1);
return (
<div className="App">
<h1>Count: {20}</h1>
<button onClick={increment}>+1</button>
<button onClick={decrement}>-1</button>
</div>
);
}
您可以看到我们只是将 21 传递给实际的 setCount。
所以我之前提到的示例应该写成:
const incrementDouble = () => {
setCount(20 + 1);
setCount(20 + 1);
};
该函数只是重复两次将状态更新为 21 的过程。
传递给 setState 的函数是状态转换指令
所以让我们改进代码!
export const useCounter = (init: number = 0) => {
const [count, setCount] = useState(init);
const increment = () => setCount((prevValue) => prevValue + 1);
const decrement = () => setCount((prevValue) => prevValue - 1);
return { count, increment, decrement };
};
此代码正常工作。
写setCount ((prevValue) => prevValue + 1) 而不是写 setCount (count + 1)。