getDerivedStateFromProps,在更改道具影响下的状态更改

Umb*_*bro 6 javascript reactjs

我单击项目->我从url获取数据https: // app / api / v1 / asset / $ {id}。数据保存在中loadItemId。我正在loadItemId从组件移动Items到组件Details,然后到组件AnotherItem。每次我点击Item道具loadItemId更改getDerivedStateFromProps方法。问题:我将点击Element D- >我的console.log看到“真”,然后我将点击Element E- >它显示的console.log truefalse同时,它应该只显示false

试图创建一个三元运算符{this.state.itemX ['completed'] ? this.start () : ''}。如果{this.state.itemX ['completed']调用函数this.start ()

代码在这里:stackblitz

图片:https : //imgur.com/a/OBxMKCd

物品

class Items extends Component {
  constructor (props) {
    super(props);
    this.state = {   
      itemId: null,  
      loadItemId: ''
    }
  }

  selectItem = (id) => {
    this.setState({
      itemId: id
    })

        this.load(id);
  }

    load = (id) => {

        axios.get
            axios({
                    url: `https://app/api/v1/asset/${id}`,
                    method: "GET",
                    headers: {
                        'Authorization': `Bearer ${token}`           
                    }
            })
            .then(response => {
                    this.setState({
                            loadItemId: response.data
                    });
            })
            .catch(error => {
                    console.log(error);
            })
}

  render () {
    return (
            <div > 
                <Item
                    key={item.id}
                    item={item}
                    selectItem={this.selectItem}
                >
                <Details
                    loadItemId={this.state.loadTime}  
                /> 
            </div>
    )
  }
Run Code Online (Sandbox Code Playgroud)

项目

class Item extends Component {
  render () {

    return (
      <div  onClick={() => this.props.selectItem(item.id}>

      </div>
    )
  } 
}
Run Code Online (Sandbox Code Playgroud)

细节

class Details extends Component {
    constructor() {
        super();
    }

  render () {
    return (
            <div> 
                <AnotherItem 
                    loadItemId = {this.props.loadItemId}        
                />       
            </div>
    )
  } 
}
Run Code Online (Sandbox Code Playgroud)

另一个项目

class AnotherItem extends Component {


  constructor() {
    super();

    this.state = {
      itemX: ''
    };
  }


  static getDerivedStateFromProps(nextProps, prevState) {
    if(nextProps.loadItemId !== prevState.loadItemId) {
      return { itemX: nextProps.loadItemId }
    }

  render () {
      console.log(this.state.itemX ? this.state.itemX['completed'] : '');

    {/*if this.state.loadX['completed'] === true, call function this.start()*/ }
    return (
            <button /*{this.state.loadX['completed'] ? this.start() : ''}*/ onClick={this.start}>
                Start
            </button>      
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Gre*_*zik 0

需要一些澄清,但我认为我仍然可以在高层解决这个问题。正如上面评论中所建议的,根据所提供的信息,您的组件 AnotherItem 实际上并不需要维护状态来确定调用 start() 方法的正确时间(尽管由于其他原因它可能需要有状态,例如如下所述)。

看来您想要实现的功能(在特定时间调用 start 方法)可以仅通过 componentDidUpdate 生命周期方法比较旧/新道具来完成。正如 React 文档所提供的, getDerivedStateFromProps 实际上是为一些“罕见”情况保留的,我认为这里不存在这些情况。相反,当收到新的 props 并满足某个条件(例如,不等于旧的 props)时,您似乎想要调用某个方法,也许执行一些计算。这可以通过挂接到 componentDidUpdate 来实现。

class AnotherItem extends Component {
   constructor(props) {
      super(props);
      this.state  = {}
   }

   start = () => { do something, perform a calculation }

  // Invoked when new props are passed
  componentDidUpdate(prevProps) {

     // Test condition to determine whether to call start() method based on new props,
     // (can add other conditionals limit number of calls to start, e.g., 
     // compare other properties of loadItemId from prevProps and this.props) .
     if (this.props.loadItemId && this.props.loadItemId.completed === true) {

         //Possibly store result from start() in state if needed
         const result = this.start();
      } 

    }
  }

    render () {
       // Render UI, maybe based on updated state/result of start method if 
       // needed
    );
  }
}
Run Code Online (Sandbox Code Playgroud)