Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getDerivedStateFromProps, change of state under the influence of changing props

I click Item -> I get data from url:https: // app / api / v1 / asset / $ {id}. The data is saved in loadItemId. I am moving loadItemId from the component Items to the component Details, then to the component AnotherItem. Each time I click Item the props loadItemId changes in the getDerivedStateFromProps method. Problem: I'll click Element D -> I see in console.log 'true', then I'll click Element E --> It display in console.log true andfalse simultaneously, and it should display only false.

Trying to create a ternary operator {this.state.itemX ['completed'] ? this.start () : ''}. If {this.state.itemX ['completed'] call the function this.start ()

Code here: stackblitz

Picture: https://imgur.com/a/OBxMKCd

Items

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>
    )
  }

Item

class Item extends Component {
  render () {

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

      </div>
    )
  } 
}

Details

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

  render () {
    return (
            <div> 
                <AnotherItem 
                    loadItemId = {this.props.loadItemId}        
                />       
            </div>
    )
  } 
}

AnotherItem

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>      
    );
  }
}
like image 581
Umbro Avatar asked Jul 12 '19 10:07

Umbro


People also ask

How do I change state with getDerivedStateFromProps?

Example. In this example, we will build a React application which will fetch the list of users and on clicking the 'fetch user' button, the Show component will get placed in the DOM and before rendering this component, getDerivedStateFromProps method is called which updates the state according to the props passed to it ...

Which methods are called when state or props is changed?

An update can be caused by changes to props or state. These methods are called in the following order when a component is being re-rendered: static getDerivedStateFromProps() shouldComponentUpdate() render()

Can we set state in getDerivedStateFromProps?

The getDerivedStateFromProps() method is used when the state of a component depends on changes of props. getDerivedStateFromProps(props, state) is a static method that is called just before render() method in both mounting and updating phase in React. It takes updated props and the current state as arguments.

How do I change state from props in React?

To update state when props change in React:Pass the props as dependencies to the useEffect hook. Every time the props change, the logic in useEffect is reran.


1 Answers

here:

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

    this.load(id);
}

you call setState(), then 'Item' and 'Details' and 'AnotherItem' call their render method. so you see log for previous 'loadItemId'.

when 'load' method work done. here:

 this.setState({
     loadItemId: response.data
 });

you setState() again, then 'Item' and 'Details' and 'AnotherItem' call their render method again. in this time you see log for new 'loadItemId'.


solution

setState both state in one place. after load method done, instead of:

 this.setState({
     loadItemId: response.data
 });

write:

 this.setState({
     itemId: id,
     loadItemId: response.data
 });

and remove:

this.setState({
  itemId: id
})

from 'selectItem' method.

like image 91
farbod Avatar answered Nov 10 '22 03:11

farbod