React:一旦data.loading为false,我如何在组件的生命周期中仅调用一次方法

时间:2018-06-29 14:46:40

标签: javascript reactjs

我有一个带有组件“ total”的React组件,每次更新时都会更改该组件:

function MyView(props) {
  const total = props.data.loading ? 0 : props.data.total;
  return (
    <p> total </p>
  );
}

组件第一次安装的总数为10。每次由于属性更改而更新组件时,总数都会增加。

有没有办法显示原始总数(在此示例中为10)?

我尝试在componentDidMount内部的this.total中进行设置,但是在调用componentDidMount时props.data.total尚不可用。与构造函数相同。仅当props.data.loading为false时,总数才可用。

5 个答案:

答案 0 :(得分:1)

您可以创建一个有状态组件,并将初始total存储在组件状态。

示例

class MyView extends React.Component {
  state = {
    initialTotal: this.props.total
  };
  render() {
    const { total } = this.props;
    const { initialTotal } = this.state;
    return (
      <div>
        <p> Total: {total} </p>
        <p> Initial total: {initialTotal} </p>
      </div>
    );
  }
}
class App extends React.Component {
  state = {
    total: 10
  };

  componentDidMount() {
    this.interval = setInterval(() => {
      this.setState(({ total }) => {
        return { total: total + 1 };
      });
    }, 1000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return <MyView total={this.state.total} />;
  }
}

答案 1 :(得分:1)

为了访问生命周期功能,必须从功能,无状态组件to a class component移出。

在下面的示例中,InitialTotal是在construstor生命周期方法中初始化的,它从未更改。

currentTotal,每次调用render函数时都会增加-重新渲染组件时(由于道具更改或状态更改)

它看起来应该像这样:

class MyView extends React.Component {
  constructor(props) {
    super(props)

    this.initialTotal = 10;
    this.currentTotal = 10;
  }
  render() {
    this.currentTotal+=1;
    return (
      <p>InitialToal: {this.initialTotal}</p>
      <p>Current Total: {this.currentTotal}</p>
    );
  }
}   

答案 2 :(得分:0)

您可以使用getDerivedStateFromProps生命周期方法。

static getDerivedStateFromProps(props, state){

        if(props.data.total && (props.data.total==10)){
             return {
                 total : props.total // show total only when its 10
              }
         }else{
             return null; // does not update state
          }
    }

答案 3 :(得分:0)

如果我正确理解您的要求...

function MyView(props) {
      // if you only need to set the value once on load just use useState.
      // the const total will be the value you pass in to useState.
      const [total, setTotal] = useState(props.data.loading ? 0 : props.data.total)

      // if its possible that the value is not available on initial load and
      // you want to set it only once, when it becomes available, you can use 
      // useEffect with useState
      useEffect(() => {
        // some condition to know if data is ready to set
        if (!props.data.loading) {
          setTotal(props.data.total)
        }

      }, [props.data.total, setTotal, props.data.loading] 
      // this array allows you to limit useEffect to only be called when 
      // one of these values change. ( when total changes in this case, 
      // as the const function setTotal will not change 
      // ( but react will fuss if its used and not in the list ).

      return (
        <p> {total} </p>
      );
    }

答案 4 :(得分:0)

我也有同样的需求。对于功能组件,我需要存储状态的初始快照,让用户玩不同的状态值并立即查看结果,最终,他们可以取消并返回初始状态。将相同的结构应用于您的问题,这就是它的外观:

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

const TestView = (props: { data: any }) => {
    // setting default will help type issues if TS is used
    const [initialTotal, setInitialTotal] = useState(props.data.total)

    useEffect(() => {
        // some condition to know if data is ready to set
        setInitialTotal(props.data.total);
        // Critical: use empty array to ensure this useEffect is called only once.       
    }, [])

    return (
        <div>
        <p> { initialTotal } </p>
        <p> { props.data.total } </p>
        </div>
    );
}

export default TestView