4
votes

Is there any proper way to access a property in the state of a child component and get its value from a parent component?

I have a component called "itemSelection" where I map through an api response to get some items like this

            <div className="row">
                {this.state.items.map(i => <Item ref="item" id={i.id} name={i.name} quantity={i.quantity} />)}
            </div>

In the Item component there a property in the state called "selected" which I want to know its value if it was true or false in the itemSelection component. I know I can pass props from itemSelection to Item but what if I want the opposite? where I can pass data from Item to itemSelection


EDITED

So, I have made a property in the parent component "itemSelection" called "selected" and I have set it to =false= (knowing that I have the same property in the child component which is set to =false= also)

in the child component I have put this line in the event handler function after I have made setState to the property selected to change it to =true=

this.props.getPropsFromChild(this.state.selected);

then in the parent component I have made this function

getPropsFromChild = (selected) => {
      this.setState({selected: selected}); 
  }

but still didn't work, I don't know if I have set it right.

2
You need to use callbacks or state management library for thatHemadri Dasari
As you @Think-Twice said you can use callbacks but this is not proper React way. Child components don't pass some state to parents. You can keep this selected state in the parent. Your child component only updates the parent's state via callbacks, don't keep its own state like that.devserkan

2 Answers

3
votes

Passing props from child to parent component works using callback functions in React. Or you can also use state management library like Redux and store the data in child component and get the data in parent component.

The example below illustrate how to send props from child to parent. I am sharing below example to make you understand how you can send props from child to parent.

ItemSelection: Parent component

      //handler function
      getPropsFromChild = (id, name) => {
            console.log(id, name);
       }

       //pass down your handler function to child component as a prop
        <div className="row">
            {this.state.items.map(i => <Item ref="item" id={i.id} name={i.name} getPropsFromChild={this.getPropsFromChild} quantity={i.quantity} />)}
        </div>

Item: Child component

componentDidMount(){
    //access handler function passed to your item component and access it using this.props and send the values as you want to the function
    this.props.getPropsFromChild(“01”, “Hi”);
}
2
votes

As tried to explain in the comments you can use callbacks for this, but try to avoid to get a value from child component like that. You can keep selected state in your parent component. Your Item component does not need to keep a state at all for this. With proper handlers from the parent, you can update your state easily.

class App extends React.Component {
  state = {
    items: [
      { id: "1", name: "foo", quantity: 1 },
      { id: "2", name: "bar", quantity: 2  },
      { id: "3", name: "baz", quantity: 3 },
    ],
    selected: "",
  }

  handleSelect = item => this.setState({ selected: item.id })

  render() {
    const { items } = this.state;
    
    return (
      <div>
      Selected item: {this.state.selected}
      {
        items.map( item =>
          <Item key={item.id} item={item} onSelect={this.handleSelect} />
        )
      }
      </div>
    );
  }
}

const Item = props => {
  const { item, onSelect } = props;
  const handleSelect = () => onSelect( item );
  
  return (
    <div style={{border: "1px solid gray"}} onClick={handleSelect}>
      <p><strong>Item id:</strong> {item.id}</p>
      <p><strong>Item name</strong>: {item.name}</p>
      <p><strong>Item quantity</strong>: {item.quantity}</p>
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>