Ad

How To Re-use React Callback For Lifting State Up?

- 1 answer

I don't understand how to abstract my callback function that is passed to the instances of my child component as a prop to lift state up to the parent component:

/* Parent */

typeCallback = (dataFromChild) => {
    var filter = {...this.state.filter}
    filter.type = dataFromChild;
    this.setState({filter}, () => console.log(this.state));
}

makeCallback = (dataFromChild) => {
    var filter = {...this.state.filter}
    filter.make = dataFromChild;
    this.setState({filter}, () => console.log(this.state));
}

...

/* Parent render() */

<Child url='http://localhost:5000/device_type' placeholder='Type' parentCallback={this.typeCallback}/>
<Child url='http://localhost:5000/device_make' placeholder='Make' parentCallback={this.makeCallback}/>

I would like to abstract my callback function to take in the name of the state variable of the parent that it should update. At the moment I have 6 instances of Child component and 6 corresponding copies of callback function tailored to update the target state variable (i.e. this.state.filter.type, this.state.filter.make)

/* Child */

handleSelectorValueCreate = () => {
    fetch(this.props.url, {
                            method:  'POST',
                            headers: {"Content-Type": "application/json"},
                            body:    val,
                          })
    .then(res => res.json())
    .then(response => {  this.setState({value: response}, () => this.sendData() ); })


sendData = () => {
    this.props.parentCallback(this.state.value);
}

/* Child render() */

<Child onChange={this.handleSelectorValueChange} />
Ad

Answer

Yes you could extend parent's prop of function's arguments to do this

/* Parent */
commonCallback = (dataFromChild, type) => {
  var filter = { ...this.state.filter };
  filter[type] = dataFromChild;
  this.setState({ filter }, () => console.log(this.state));
};

....
<Child
   url="http://localhost:5000/device_type"
   placeholder="Type"
   parentCallback={liftState => {
    /* Use type as second parameter for differentiating*/
    this.commonCallback(liftState, 'type');
   }}
/>

This creates common callback with two parameters - stateToLift and type.

Ad
source: stackoverflow.com
Ad