ReactJs:如何防止 componentWillUpdate 多次重新渲染

ReactJs : How to prevent componentWillUpdate from re-rendering multiple times

我正在创建一个简单的 Todo 应用程序,我正在使用 componentDidMount 来显示数据库中的数据。但问题是,一旦我添加了新数据,数据就会被存储,但除非我刷新它,否则它不会显示在页面上。

然后我遇到了componentDidUpdate。它运行完美,但它会重新渲染多次,我的意思是它不断请求服务器检查新数据。 我在后端使用 Express

谁能告诉我如何防止这种情况发生?或者有没有更好的解决办法?

这是当前代码:

  class Navbar extends Component {
  state = {
    userArray: [],
    username: "",
    email: ""
  };

  //Storing the Data

  addBtn = e => {
    e.preventDefault();

    var data = {
      username: this.state.username,
      email: this.state.email
    };

    fetch("/user", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(data)
    })
      .then(response => {
        if (response.status >= 400) {
          throw new Error("Bad response from server");
        }
        return response.json();
      })
      .then(data => {
        console.log(data);
        if (data === "success") {
          console.log("Yay");
        }
      })
      .catch(err => {
        console.log(err);
      });
    console.log(this.state.userArray);
  };


  componentDidMount() {
    this.displayData();
  }

  componentWillUpdate() {
    this.displayData();
  }

//显示数据

  displayData() {
    fetch("/user")
      .then(data => data.json())
      .then(data => {
        this.setState({
          userArray: data
        });
      });
  }

  //Handling the input values

  logChange = e => {
    this.setState({
      [e.target.name]: e.target.value
    });
  };

为此,你需要先了解componentDidMount和componentWillUpdate在React中是如何工作的。 他们是 lifecycle methods 的反应者。

componentDidMount 在安装组件后被调用。它只被调用一次,如果没有卸载并再次安装,就再也不会被调用。

每次状态发生变化和重新渲染时都会调用 componentWillUpdate。

正如@trixn 评论的那样: 当你有数据时,你需要在 addBtn 中调用 this.setState() 而不是重复调用 this.displayData()

componentDidMount是第一次加载的正确位置,然后,创建新的Todo后,需要在POST[=19=之后立即刷新列表] 请求完成

.then(data => {
  console.log(data);
  if (data === "success") {
    console.log("Yay");
    this.displayData();
  }
})

为了提高性能,你应该在POST之后return新的Todo记录,所以你只需要将它推送到状态列表userArray,而不需要再次获取整个列表

那么,让我们尝试了解为什么对服务器有大量调用。

创建 componentDidMount 时,您调用了 displayData,然后调用了 setState。一旦调用 setstate,它就会调用 componentDidUpdate,然后再次调用 displayData,然后再调用 setState。循环继续(可能直到你 运行 内存不足)。

你可以试试这个 class:

import React from 'react';

export default class Navbar extends React.Component {
    state = {
        userArray: [],
        username: '',
        email: ''
    };

    componentDidMount() {
        this.displayData();
    }

    addBtn = e => {
        e.preventDefault();

        var data = {
            username: this.state.username,
            email: this.state.email
        };

        fetch('/user', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(data)
        })
            .then(response => {
                if (response.status >= 400) {
                    throw new Error('Bad response from server');
                }
                return response.json();
            })
            .then(data => {
                console.log(data);
                if (data === 'success') {
                    this.displayData();
                }
            })
            .catch(err => {
                console.log(err);
            });
    };

    displayData() {
        fetch('/user')
            .then(data => data.json())
            .then(data => {
                this.setState({
                    userArray: data
                });
            });
    }
}

基本上,我所做的是在 componentDidUpdate 中删除对 displayData 的调用,然后在 ApI 调用成功时调用 displayData

大家都答对了,但是有个小错误。

您应该在 if condition

之外调用 displayData()
.then(data => {
  console.log(data);
  if (data === "success") {
    console.log("Yay");
  }
   this.displayData();
})