为什么钩子的代码(功能)不断渲染? (与班级相比)

时间:2021-02-19 10:04:48

标签: javascript reactjs react-hooks react-state react-lifecycle

我刚开始反应...

此代码在 3 秒后使用布尔值简单呈现。

但是下面的代码几乎每三秒就不断渲染..渲染..渲染....

import React, { useState } from "react";

const App = () => {
  const [isLoading, setIsLoading] = useState(true);

  setTimeout(() => {
    setIsLoading(!isLoading);
  }, 3000);

  return <h1>{isLoading ? "Loading" : "we are ready"}</h1>;
};

export default App;


但是这段代码运行良好。是什么原因?

import React, { Component } from "react";

class App extends React.Component {
  state = {
    isLoading: true,
  };

  componentDidMount() {
    setTimeout(() => {
      this.setState({
        isLoading: false,
      });
    }, 3000);
  }

  render() {
    return <div>{this.state.isLoading ? "Loading..." : "we are ready"}</div>;
  }
}

export default App;

3 个答案:

答案 0 :(得分:4)

每次渲染都会调用一个函数组件。这意味着在状态更改后的每次重新渲染时都会创建超时,就像在您的第一个示例中一样实现。要使用组件生命周期,您应该使用 useEffect 钩子:https://reactjs.org/docs/hooks-reference.html#useeffect

import React, { useEffect, useState } from "react";

const App = () => {
  const [isLoading, setIsLoading] = useState(true);

  // Set a timeout ONCE when the component is rendered for the first time
  // The second argument [] signifies that nothing will trigger the effect during re-renders
  useEffect(() => {
    setTimeout(() => {
      setIsLoading(false);
    }, 3000);
  }, [])

  return <h1>{isLoading ? "Loading" : "we are ready"}</h1>;
};

export default App;

答案 1 :(得分:0)

因为您正在使用状态中的真值初始化 isLoading。并且每当状态更改时,功能组件都会重新呈现,并且在基于类的组件中不会发生,因为您使用了组件生命周期方法。您应该在功能组件中使用“useEffect”。

  useEffect(() => {
    setTimeout(() => {
      setIsLoading(!isLoading);
    }, 3000);
  });

你可以在这里阅读https://reactjs.org/docs/hooks-effect.html

答案 2 :(得分:0)

不幸的是,MubtadaNaqvi 的回答会导致无限循环。您应该正确应用 useEffect:

  useEffect(() => {
    setTimeout(() => {
      setIsLoading(isLoading => !isLoading);
    }, 1000);
  }, [])