Champion
Champion

Reputation: 774

Pass data from child to parent React

I need to pass state (month) from Child to Parent. It works well after updating state (month) in Child (handleMonth), but does not work if nothing updated ... got just undefined.

I need this state in order to send it into unrelated component like: this.props.navigation.state.params.month

Parent component

class Home extends Component {
  constructor(){
    super();
    this.state = {
      month: moment().format("MMMM YYYY")
    }

    this.getData = this.getData.bind(this);
  }
    getData = (val) => {
        this.setState({month: val});     
    }
// this I need to send month as props to unrelated component(Screen)
    showList = () => {
      this.props.navigation.navigate('CostDetailsMonth', {
        month: this.state.month });
      this.getData()
    }
render(){
    return (
        <View style={styles.container}>
         <Costs showList={this.showList} sendData={this.getData} />
        </View>
)}}

Child component

class Costs extends Component {
  constructor(props){
    super(props)
    this.state = {
      month: moment().format("MMMM YYYY")
    }
  }

  handleMonth= (itemValue) => {
    this.setState({month: itemValue});
    // send selected month to parent (HOME)     
    this.props.sendData(itemValue); 
  }
  
  render () {
     return (
        <View style={styles.data}>
          <TouchableOpacity onPress={this.props.showList}>
            <SelectMonth 
              handleMonth={this.handleMonth}
            />
            <Text style={styles.total}>{totalMonth}</Text>
          </TouchableOpacity>
        </View>
)}}

I got 'undefined' while started App and then select the month May got 'May'. After clicking on May and return back again 'undefined'. Not sure if it's clear enough, but I need a help.

PS. Can't use Redux in this case because component 'date select' too complicated.

Upvotes: 0

Views: 723

Answers (2)

HMR
HMR

Reputation: 39310

If you pass a setValue function to a child component from Parent that sets a value managed by Parent you may as well pass the value itself and not copy it in Child in the local state.

const Child = ({ value, setValue }) => (
  //no point in copying value to local state here
  //  just use the value that's been passed by Parent
  <input
    type="text"
    onChange={(e) => setValue(e.target.value)}
    value={value}
  />
);
const Parent = () => {
  //both value and setter are defined in Parent
  const [value, setValue] = React.useState('');
  //just pass both the value setter and the value to Child
  return <Child value={value} setValue={setValue} />;
};
ReactDOM.render(
  <Parent />,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>


<div id="root"></div>

Upvotes: 1

po.pe
po.pe

Reputation: 1162

You could use componentDidMount() like

componentDidMount(){
  this.props.sendData(itemValue); 
}

This will update the parent state once the child component is successfully mounted

Upvotes: 0

Related Questions