2

I am trying to learn React JS and I am working on a personal project. I am stuck because I could not pass the value of an input field in a child component to the state of the parent component.

I have tried using the onChange event but for some reason the function it is calling, handleChange, is not getting triggered.

Here is a snippet from the Parent component:

class App extends Component {
    state = {
        myArray: [{ //myArray is being updated by another child component, which sets the values for id and amount; this works fine
                id: 1,
                amount: 12
            },
            {
                id: 2,
                amount: 23
            }
        ]
        total: 0 //expected value for total is 35
    };

    handleChange = e => {
        const { name, value } = e.target
        this.setState({
            [name]: value
        });
    }

    render() {
        return ( 
            <Child 
            handleChange={this.handleChange}
            myArray={this.state.myArray} />
            )
        }
    }

And here is a snippet from the Child component:

class Child extends Component {

    render() {
        const { myArray, handleChange } = this.props;

        const totalAmount = myArray.reduce(function (a, b) {
            return a + b.amount;
        }, 0);

        return (
        <div>
            <label htmlFor="total"> Total Amount: </label>
            <input id="total"
            name="total"
            type="number"
            placeholder="0.00"
            value={totalAmount}
            onChange={e => handleChange(e)}
            /> 
        </div>
        )
    }
}

The value in of the total input field renders correctly. However, what I am trying to achieve is every time this input field value is changed (when the other child component updates the myArray values and therefore the sum also changes), I wish to update the total value in the state of the Parent component.

1

2 Answers 2

2

You're executing the callback immediately and not passing the event object. Try like this

onChange = {e => handleChange("total")(e)}

Also inside handleChange your argument's name is wrong

handleChange = propertyName => e => {
    this.setState({
        [property]: e.target.value
    });
}

Should be

handleChange = property => e => {
    this.setState({
        [property]: e.target.value
    });
}
Sign up to request clarification or add additional context in comments.

4 Comments

I overlooked the argument name and I have already corrected it. I have modified my post above and tried to pass the event object as you said, but it's still not working. :( I added some console.log in the handleChange function but it's really not getting triggered.
Can you post a sandbox?
Wait! I got it to print the console.log in the handleChange when I manually changed the "total" text field. But what I want is to invoke the handleChange function even when the value in this "total" text field is updated automatically by some other logic in another component. Should I still use the onChange attribute for this?
here is a sandbox: codesandbox.io/s/quiet-framework-cu0gb?fontsize=14 The handleChange function on ParentComponent.js is still not getting triggered.
0

You dont need to pass field name manually, you can get it from the event. First give your input a name

<input name="total" ...etc >

Then, you can just receive event in your handleChange

handleChange = e => {
   const { name, value } = e.target
   this.setState({
       [name]: value
   )}
  }

The way you call it in Child Component should be

onChange={handleChange}

see the code here https://codesandbox.io/embed/unruffled-pascal-d5p2q?fontsize=14

For better structure, it`d be better if you put childComponent2 next to childComponent1. It only need total props.

8 Comments

No worries, just mark this question as answered if you solve it
The problem is still not solved. The handleChange function on the ParentComponent is still not getting triggered. Here is a sandbox: codesandbox.io/s/quiet-framework-cu0gb?fontsize=14
it's the way you call it in child component, see updated answer
You meant in ./components/ChildComponent2.jsx right? Still the same. I have place a console logging in the handleChange function and nothing gets printed in the console.
I still can see my change through the link I shared
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.