Published on

译: 避免5个React useState的错误使用

Authors
  • avatar
    Name
    Deng Hua
    Twitter

翻译至: 5 React useState Mistakes That Can Put Your Job at Risk: Avoid These Pitfalls!

目录

忽略了不可变规则

React 状态是Immutable(不可变)的,这意味着你永远不应该直接改变它。一个常见的错误是意外修改状态对象而不是创建新的状态对象。

改变状态可能会导致不可预测的行为,并使跟踪变化变得困难。

始终使用 useState 提供的 setter 函数来更新状态并确保不变性。

请记住,不变性是维持 React 组件稳定且可预测状态的关键。

Bad:

// 直接更改状态
const [count, setCount] = useState(0);

function increment() {
  count += 1; // 避免这个
  setCount(count); // 这不会触发re-render
}

Good:

const [count, setCount] = useState(0);

function increment() {
  setCount((prevCount) => prevCount + 1);
}

错误理解异步更新

React 的状态更新可能是异步的,这在连续执行多个更新时可能会导致意外结果。

如果更新时依赖于先前的状态,则使用 setter 函数的回调语法对于确保准确的结果至关重要。

未能考虑状态更新的异步性质可能会导致数据不一致,并让您感到困惑。

Bad:

const [count, setCount] = useState(0);

function incrementTwice() {
  setCount(count + 1);
  setCount(count + 1);
  console.log(count); // Outputs 0, not 2
}

Good:

const [count, setCount] = useState(0);

function incrementTwice() {
  setCount((prevCount) => prevCount + 1);
  setCount((prevCount) => prevCount + 1);
  console.log(count); // Outputs 2
}

过度使用状态来获取派生值

useState hook非常适合管理简单的状态值,但它不适用于计算复杂的派生值。

严重依赖状态来获取派生值可能会导致不必要的重新渲染并对性能产生负面影响。

相反,利用memoization技术(例如 useMemo 或自定义Memo函数)来计算和存储派生值,从而减少计算负载并优化您的 React 组件。

Bad:

const [count, setCount] = useState(0);
const doubleCount = count * 2;

function handleClick() {
  setCount(count + 1);
}

Good:

const [count, setCount] = useState(0);

const doubleCount = useMemo(() => count * 2, [count]); // 只有count变化才会重新计算

function handleClick() {
  setCount((prevCount) => prevCount + 1);
}

忽略相关的状态变量分组

随着 React 组件的增长,很容易为每个状态变量生成一长串单独的 useState hook。

但是,这种方法可能会使您的代码更难以管理和理解。

相反,请考虑将相关状态变量分组为对象或自定义数据结构。

通过逻辑地组织状态,您可以提高代码可读性,减少混乱,并更轻松地推断组件的状态。

Bad:

const [name, setName] = useState('');
const [age, setAge] = useState(0);
const [city, setCity] = useState('');

Good:

const [user, setUser] = useState({
  name: '',
  age: 0,
  city: '',
});

function handleInputChange(event) {
  setUser((prevUser) => ({
    ...prevUser,
    [event.target.name]: event.target.value,
  }));
}

违反单一来源原则

在 React 中,遵循状态具有单一事实来源的原则非常重要。

当多个 useState hook或状态变量保存相同或相关的数据时,可能会出现不一致和同步问题。

为了避免这种错误,请考虑使用更高级的状态管理库(例如 Redux 或 Context API)来集中状态管理,以确保单一事实来源并更好地控制和协调应用程序的状态。

Bad:

const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [fullName, setFullName] = useState('');

function handleInputChange(event) {
  if (event.target.name === 'firstName') {
    setFirstName(event.target.value);
    setFullName(`${event.target.value} ${lastName}`);
  } else if (event.target.name === 'lastName') {
    setLastName(event.target.value);
    setFullName(`${firstName} ${event.target.value}`);
  }
}

Good:

const [user, setUser] = useState({
  firstName: '',
  lastName: '',
  fullName: '',
});

function handleInputChange(event) {
  setUser((prevUser) => ({
    ...prevUser,
    [event.target.name]: event.target.value,
    fullName: `${prevUser.firstName} ${prevUser.lastName}`,
  }));
}