React Hooks 和 React 生命周期方法

React Hooks and React lifecycle Methods

我是 reactjs 的新手并且是原生的。在开始学习基础知识时,我找到了有关反应钩子和反应生命周期方法的各种信息。我知道在 React 16.3 之前有 7 个生命周期方法,但现在只有 6 个。任何人都可以详细说明这个生命周期方法并用一些例子来反应挂钩。这可能会帮助我学得更快。 谢谢

在 React classes 中,你有生命周期函数和状态来做事,但你没有在功能组件中使用它们。 React defs 提出了 hooks ,您可以在其中简化代码并通过在自定义挂钩中捆绑某些功能来更好地重用代码。这在以前使用 class 组件是不可能的。即使使用 Vue 中使用的混合插件,它们现在也具有与钩子类似的组合 api。

假设您希望拥有计数器功能,当计数器发生变化时进行记录,具有向上和向下功能以及计数器值。

在 class 中你需要维护你用 this.up 和 this.down 改变的 this.state.counter 所以你可以在计数器 class 中实现它extends React.Component 或 React.PureComponent 并有一个使用计数器的组件 extends Counter 但该组件仍然可以只有一个计数器。在钩子中,您可以使用自定义钩子实现一个计数器,并在一个组件中有多个计数器。

const {
  useState,
  useEffect,
  useCallback,
  useRef,
  memo,
} = React;

//hooks, also custom hooks always start with "use"
const useCounter = (name, initialValue = 1) => {
  //local counter value and function to change it
  const [counter, setCounter] = useState(initialValue);
  //ref created on mount with previous counter value
  const countRef = useRef(initialValue);
  //up and down functions created with useCallback so they
  //  will be created on mount and never change
  const up = useCallback(
    () => setCounter((c) => c + 1),
    []
  );
  const down = useCallback(
    () => setCounter((c) => c - 1),
    []
  );
  //effect that will log when counter changes
  useEffect(() => {
    if (countRef.current !== counter) {
      console.log(`counter ${name} changed to`, counter);
      countRef.current = counter;
    }
  }, [counter, name]);
  //return up, down and counter
  return { up, down, counter };
};
//using memo makes UP2 a pure component so it'll not re
//  render since up is created with useCallback and is
//  not re created therefore the props passed to UP2 
//  don't change
const UP2 = memo(function UP2({ up, name }) {
  console.log(`UP2 for ${name} will only render once`);
  return (
    <button
      onClick={() => {
        //state updates are batched in synchronous
        //  event handlers so "chaged to" will log
        //  only once
        up();
        up();
      }}
    >
      +2
    </button>
  );
});

const App = () => {
  //first counter
  const {
    up: up1,
    down: down1,
    counter: counter1,
  } = useCounter('counter one');
  //second counter
  const {
    up: up2,
    down: down2,
    counter: counter2,
  } = useCounter('counter two', 2);
  return (
    <div>
      <div>
        <button onClick={up1}>UP</button>
        <button onClick={down1}>Down</button>
        <UP2 up={up1} name={'counter one'} />
        {counter1}
      </div>
      <div>
        <button onClick={up2}>UP</button>
        <button onClick={down2}>Down</button>
        <UP2 up={up2} name={'counter two'} />
        {counter2}
      </div>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));
<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="root"></div>