【问题标题】:React class old lifeCycle methods into hooks将类旧的 lifeCycle 方法反应成钩子
【发布时间】:2021-04-05 14:27:08
【问题描述】:

我需要用 useEffect 钩子重写这个旧的 lifeCycle 方法,但我不确定如何。

componentDidMount() {
    document.addEventListener("mousedown", this.handleClickOutside);
    this.setState({
      defaultSelectText: this.props.defaultText
    });
  }

  componentWillUnmount() {
    document.removeEventListener("mousedown", this.handleClickOutside);
  }

我尝试过这种方式,但并没有真正奏效:

useEffect((props) => {
    document.addEventListener("mousedown", this.handleClickOutside);
    defaultSelectText(props.defaultText)

 }, []);

可重现示例:https://codesandbox.io/s/weathered-sun-ej9tp?file=/src/DropDownSelect.js

【问题讨论】:

标签: javascript reactjs ecmascript-6 react-hooks


【解决方案1】:

这有两个部分:

  1. 添加和删除事件监听器
  2. 将 props 转换为挂载状态

1。添加和移除事件监听器

使用useEffect 是对的,但useEffect 不会将任何参数传递给它的回调。要删除侦听器,请返回一个清理函数:

useEffect(() => {
    const handler = handleClickOutside;
    document.addEventListener("mousedown", handler);
    return () => {
        document.removeEventListener("mousedown", handler);
    };
}, []);

请注意,我们捕获了在handler 中设置的函数,以便我们可以确保删除相同的函数(以防handleClickOutside 被重新创建,就像函数有时在函数组件中所做的那样)。

2。将 props 转换为挂载状态

不要。 :-) 道具是您的父组件管理的状态。你的组件不应该将 props 复制到 state,99.9% 的情况下它是一种反模式;相反,它应该只使用道具。如果组件需要能够更改 prop 的值,则父组件应该向它传递一个函数来执行此操作。有关不这样做的更多信息,请参阅documentation for the class component getDerivedStateFromProps function

在您的情况下,您只是将道具复制到安装状态,这意味着未使用安装后对道具的更新。在您需要这样做的非常罕见用例中,与钩子等效的是使用 useState 的 prop 作为初始值:

function Example({defaultText}) {
    const [defaultSelectText, setDefaultSelectText] = useState(defaultText);
    // ...
}

为了完整起见,对于非常罕见的用例,您需要在更新 prop 时更新 state 属性,您可以使用 useEffect

function Example({defaultText}) {
    const [defaultSelectText, setDefaultSelectText] = useState(defaultText);
    // ...
    useEffect(() => {
        setDefaultSelectText(defaultText);
    }, [defaultText]); // <== Dependency is the prop
    // ...
}

...但请注意,该特定示例毫无意义;状态值只是反映道具。在将其设置为有意义的状态时,您必须对价值做一些事情。

【讨论】:

  • 我猜是document.removeEventListener 在返回,对吧?
  • @RulerNature - 嘿,是的。 :-) 另外,我意识到您只是在安装时复制道具,而不是稍后,所以我最初的示例并不完全相同。我已经修好了。
【解决方案2】:

你快到了。 对于componentDidMount,您将空数组作为依赖项传递,这意味着传递给 useEffect 的回调函数只会被调用一次,即在第一次渲染/安装组件之后。对于componentWillUnmount ,您返回您希望在卸载操作中调用的函数。

useEffect((props) => {
    document.addEventListener("mousedown", this.handleClickOutside);
    defaultSelectText(props.defaultText);

    return () => document.removeEventListener("mousedown", this.handleClickOutside);

 }, []);

【讨论】:

    【解决方案3】:

    代码如下:

    useEffect(() => {
        const handler = handleClickOutside;
        document.addEventListener("mousedown", handler); // Will be executed when component did mount
        defaultSelectText(props.defaultText); // Will be executed when component did mount
    
        return () => document.removeEventListener("mousedown", handler); // Will be executed when component will unmounted
     }, []);
    

    编码愉快:)

    【讨论】:

      猜你喜欢
      • 2021-03-27
      • 2020-09-06
      • 1970-01-01
      • 2020-02-16
      • 2020-09-17
      • 2020-11-01
      • 2019-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多