【问题标题】:componentDidUpdate vs componentDidMountcomponentDidUpdate 与 componentDidMount
【发布时间】:2021-05-21 03:05:11
【问题描述】:

当满足以下条件时,我需要确保输入元素是焦点:

  • DOM 可用并且
  • 属性已更改

问题:我需要将我的代码放在componentDidUpdatecomponentDidMount 中还是只需componentDidUpdate 就足够了?

    private makeSureInputElementFocused() {
        if (this.props.shouldGetInputElementFocused && this.inputElement !== null) {
            this.inputElement.focus();
        }

    }

    componentDidMount() {
        this.makeSureInputElementFocused(); // <-- do i need this?
    }
    componentDidUpdate() {
        this.makeSureInputElementFocused();
    }

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    您必须同时使用两者。

    componentDidMount()

    componentDidMount() 在组件安装后立即调用。需要 DOM 节点的初始化应该放在这里。如果您需要从远程端点加载数据,这是实例化网络请求的好地方。在此方法中设置状态将触发重新渲染。

    componentDidUpdate()

    componentDidUpdate() 在更新发生后立即调用。 初始渲染不调用此方法

    您也可以将其放入 render() 方法中,这似乎适合您的情况,因为您总是想检查焦点。那你就不用放到componentDidMount()componentDidUpdate()里面了

    【讨论】:

    • 假设inputElement指的是React使用render的返回值生成的DOM节点,你怎么能在render的body中与这个DOM节点交互,在那个返回值之前提供给 React?
    【解决方案2】:

    您的每个条件都要求您将代码分别放在 1 个函数中:

    • DOM 可用并且 - componentDidMount
    • 属性已更改 - componentDidUpdate

    所以你必须把两个函数都放在里面。
    另一种选择是在componentDidMount 中调用setState(),以便调用componentDidUpdate

    【讨论】:

      【解决方案3】:

      componentDidMount()

      componentDidMount() 将在组件安装后立即呈现。这个方法只会渲染一次,所有需要 DOM 节点的初始化都应该在这里。在此方法中设置状态将触发重新渲染。

      componentDidUpdate()

      componentDidUpdate() 每次更新时都会立即调用。初始渲染不调用此方法。

      你可以从下面这个例子中了解更多

      import React from 'react';
      
      class Example extends React.Component{
        constructor(props) {
          super(props);
          this.state = {
            count: 0
          };
        }
        componentDidMount() {
      
          //This function will call on initial rendering.
          document.title = `You clicked ${this.state.count} times`;
      
        }
        componentDidUpdate() {
           document.title = `You clicked ${this.state.count} times`;
         }
      
        render(){
          return(
            <div>
            <p>You clicked {this.state.count} times</p>
            <button onClick={() => this.setState({ count: this.state.count + 1 })}>
              Click me
            </button>
          </div>
          )
        }
      }
      export default Example;
      

      您可以通过注释和取消注释这两种方法来理解。

      【讨论】:

        【解决方案4】:

        componentDidUpdate 在初始渲染时不会被调用(参见https://reactjs.org/docs/react-component.html#componentdidupdate),因此您可能必须像示例中那样调用它两次。

        【讨论】:

          【解决方案5】:

          在 React v16.7.0-alpha 中,您可以使用 useEffect 钩子:

          import React, { useEffect, useRef } from "react";
          
          function InputField() {
            const inputRef = useRef();
          
            useEffect(() => {
              inputRef.current.focus();
            });
          
            return <input ref={inputRef} />;
          }
          

          来自docs

          如果你熟悉 React 类生命周期方法,你可以想 useEffect Hook 为 componentDidMount、componentDidUpdate 和 componentWillUnmount 组合。

          Example

          注意:如前所述,这不适用于基于类的组件。

          【讨论】:

          • 这不能回答问题并且不适用于基于类的组件。
          • 这适用于非基于类的功能组件。
          猜你喜欢
          • 1970-01-01
          • 2016-10-16
          • 1970-01-01
          • 2019-06-30
          • 2020-11-28
          • 2021-04-03
          • 1970-01-01
          • 1970-01-01
          • 2021-08-05
          相关资源
          最近更新 更多