react hook

只在最顶层使用 Hook

不要在循环,条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层调用他们。遵守这条规则,你就能确保 Hook 在每一次渲染中都按照同样的顺序被调用。这让 React 能够在多次的 useState 和 useEffect 调用之间保持 hook 状态的正确

不像 class 中的 this.setState,更新 state 变量总是替换它而不是合并它。

Function Component:

function ProfilePage(props) {
  setTimeout(() => {
    // 就算父组件 reRender,这里拿到的 props 也是初始的
    console.log(props);
  }, 3000);
}

Class Component:

class ProfilePage extends React.Component {
  render() {
    setTimeout(() => {
      // 如果父组件 reRender,this.props 拿到的永远是最新的。
      // 并不是 props 变了,而是 this.props 指向了新的 props,旧的 props 找不到了
      console.log(this.props);
    }, 3000);
  }
}
https://github.com/dt-fe/weekly/blob/master/95.%E7%B2%BE%E8%AF%BB%E3%80%8AFunction%20VS%20Class%20%E7%BB%84%E4%BB%B6%E3%80%8B.md

Hooks 也具有 capture value 特性

function MessageThread() {
  const [message, setMessage] = useState("");

  const showMessage = () => {
    alert("You said: " + message);
  };

  const handleSendClick = () => {
    setTimeout(showMessage, 3000);
  };

  const handleMessageChange = e => {
    setMessage(e.target.value);
  };

  return (
    <>
      <input value={message} onChange={handleMessageChange} />
      <button onClick={handleSendClick}>Send</button>
    </>
  );
}

在线 Demo

在点击 Send 按钮后,再次修改输入框的值,3 秒后的输出依然是 点击前输入框的值。这说明 Hooks 同样具有 capture value 的特性。

利用 useRef 可以规避 capture value 特性:

function MessageThread() {
  const latestMessage = useRef("");

  const showMessage = () => {
    alert("You said: " + latestMessage.current);
  };

  const handleSendClick = () => {
    setTimeout(showMessage, 3000);
  };

  const handleMessageChange = e => {
    latestMessage.current = e.target.value;
  };
}

只要将赋值与取值的对象变成 useRef,而不是 useState,就可以躲过 capture value 特性,在 3 秒后得到最新的值。

这说明了利用 Function Component + Hooks 可以实现 Class Component 做不到的 capture props、capture value,而且 React 官方也推荐 新的代码使用 Hooks 编写

原文地址:https://www.cnblogs.com/cschen588/p/12666920.html