代码之家  ›  专栏  ›  技术社区  ›  Hemadri Dasari

useState和useEffect之间有什么区别?

  •  1
  • Hemadri Dasari  · 技术社区  · 6 年前

    我在react v16中看到了这两个新概念。

    useState setState 用钩子和 useEffect 类似于生命周期方法。

    使用状态 使用效果 ?

    2 回复  |  直到 6 年前
        1
  •  39
  •   Yangshun Tay    6 年前

    简单地说,两者都有 useState useEffect 增强功能组件,使它们做类可以做但功能组件(没有挂钩)不能做的事情:

    • 允许功能组件具有 状态 喜欢 this.state 类内组件。
    • 使用效果 允许功能组件具有 componentDidMount , componentDidUpdate componentWillUnmount

    有关进一步说明,请参阅以下示例:

    class CounterClass extends React.Component {
      constructor(props) {
        super(props);
        this.state = { count: 1 };
      }
      
      render() {
        return <div>
          <p>Count: {this.state.count}</p>
          <button onClick={() => this.setState({ 
            count: this.state.count + 1
          })}>Increase</button>
        </div>;
      }
    }
    
    function CounterFunction() {
      const [count, setCount] = React.useState(1);
      return (
        <div>
          <p>Count: {count}</p>
          <button onClick={() => 
            setCount(count + 1)}
          >Increase</button>
        </div>
      );
    }
    
    ReactDOM.render(
      <div>
        <CounterClass />
        <CounterFunction />
      </div>
    , document.querySelector('#app'));
    <script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
    
    <div id="app"></div>

    使用效果

    class LifecycleClass extends React.Component {
      componentDidMount() {
        console.log('Mounted');
      }
      
      componentWillUnmount() {
        console.log('Will unmount');
      }
      
      render() {
        return <div>Lifecycle Class</div>;
      }
    }
    
    function LifecycleFunction() {
      React.useEffect(() => {
        console.log('Mounted');
        return () => {
          console.log('Will unmount');
        };
      }, []); // Empty array means to only run once on mount.
      return (
        <div>Lifecycle Function</div>
      );
    }
    
    ReactDOM.render(
      <div>
        <LifecycleClass />
        <LifecycleFunction />
      </div>
    , document.querySelector('#app'));
    <脚本src=“https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js“></脚本>
    <脚本src=“https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react dom.development.js“></脚本>
    

    阅读更多关于 useState useEffect

        2
  •  14
  •   Arsh Shaikh Nguyen You    4 年前

    对于 useState()

    首先,我们有 功能部件 state 功能部件 是一个 无状态组件 .

    但是 有状态 useState .


    对于 useEffect()

    首先,与 无状态功能组件 ,我们没有 组件生命周期挂钩 . 换句话说,只要你想使用 类组件 .

    现在,我们可以使用 组件生命周期挂钩 不使用 . 它是通过使用 useEffect . 换句话说,现在只要我们想使用 ,我们已经有两个选项,使用 或者用钩子 useEffect


    两者之间的确切区别是什么 useState 使用效果 ?

    简言之, 使用状态 无国籍的 使用效果 允许我们 功能部件 利用 类组件 .

        3
  •  7
  •   Simar Singh    5 年前

    useState useEffect state / setState 和组件生命周期方法(例如。 componentDidMount componentDidUpdate ,及 componentWillUnmount )

    useState() 简单来说,它允许您在功能组件中拥有状态访问器。

    useEffect() 可以合并 组件安装 , ,及 组件将卸载

    你可以从官方文件中解读我这里要讨论的大部分内容 hooks . 在工作中更容易看到挂钩,而不是从文本中推理。

    预渲染生命周期

    预渲染生命周期 相当于 componentWillReceiveProps getDerivedStateFromProps componentWillMount 可以是我们在返回JSX(react节点)之前在函数组件中首先做的事情,因为函数本身相当于 render(…)

    我们不需要钩子来处理渲染前生命周期事件。

    渲染后生命周期

    渲染后生命周期 事件,那些相当于 组件更新 componentDidUnmount 基于类的组件。

    我们需要 ** **_useEffect(…)_** 处理这些渲染后生命周期事件的步骤 **因为我们不能在主组件函数中写入与这些生命周期事件相关的逻辑,因为这些事件应该在组件函数将JSX(react node)返回给 react-dom 渲染器。

    我们知道 useEffect(fn, […watchStates]) ,接受2个参数。

    1. fn 使用效果 根据(2)参数给出的更改跟踪的值,在每个渲染周期后调用此函数作为副作用运行。功能 ,可以返回另一个函数,该函数应在效果函数再次运行或组件卸载之前作为清理运行
    2. […watchValues ] :(可选) 使用效果 此阵列中的轨迹值已从上一个渲染周期更改,然后仅显示效果 fn 被调用。如果未给出此参数,则效果将在每个渲染周期中运行。

    如果我们不把逻辑全部通过,我们就一起通过 fn 将在每个渲染周期后调用。

    如果我们传递(2)个数组的值,则组件需要监视更改并调用 fn

    最棘手的部分是使用空数组 [] 作为(2)论点,我们可以限制副作用逻辑 若仅在安装阶段执行,因为并没有任何更改,则在后续渲染周期触发后,效果挂钩将监视 再一次。

    import React, { useState, useEffect } from "react";
    export default props => {
      console.log("componentWillMount");
      console.log("componentWillReceiveProps", props);
      const [x, setX] = useState(0);
      const [y, setY] = useState(0);
      const [moveCount, setMoveCount] = useState(0);
      const [cross, setCross] = useState(0);
      const mouseMoveHandler = event => {
        setX(event.clientX);
        setY(event.clientY);
      };
      useEffect(() => {
        console.log("componentDidMount");
        document.addEventListener("mousemove", mouseMoveHandler);
        return () => {
          console.log("componentDidUnmount");
          document.removeEventListener("mousemove", mouseMoveHandler);
        };
      }, []); // empty-array means don't watch for any updates
      useEffect(
        () => {
          // if (componentDidUpdate & (x or y changed))
          setMoveCount(moveCount + 1);
        },
        [x, y]
      );
      useEffect(() => {
        // if componentDidUpdate
        if (x === y) {
          setCross(x);
        }
      });
      return (
        <div>
          <p style={{ color: props.color }}>
            Your mouse is at {x}, {y} position.
          </p>
          <p>Your mouse has moved {moveCount} times</p>
          <p>
            X and Y positions were last equal at {cross}, {cross}
          </p>
        </div>
      );
    };
    

    代码片段很简单,并且是不言自明的。你可以试穿一下 CodePen .

    需要注意的一件重要事情是,如果要在效果内部进行状态更改,请确保将内部正在更改的状态从手表阵列中排除。

    例如,在第二个效果(计算鼠标移动的效果)中,我们仅在x和y上的更新时通过传递触发它 [x , y]

    1. 观察x和y的变化来记录鼠标的移动在逻辑上是正确的
    2. 如果我们不将moveCount排除在监视范围之外,这个useEffect将进入一个无限循环,因为我们将更新同样的值,我们也在监视更改

    Medium 出版如果您喜欢这件艺术品,或者有任何意见和建议,请 鼓掌 在…上 中等 .