Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onChange event for React child component to update state

I'm trying to learn how to implement a React form (ES6 syntax) and pass the onChange events for each field up to a controller parent component which is responsible for updating the state. This works fine for standard html elements, however I am trying a pre-canned Datepicker (https://www.npmjs.com/package/react-bootstrap-date-picker) for a date field and can't readily pass the event back up to the parent in the same way. Is there a simple way to address this?

Controller Component

   class Parent extends React.Component {     constructor (props) {         super(props);         this.state = {job: ''}      }      setJobState(event) {         var field = event.target.name;         var value = event.target.value;         this.state.job[field] = value;         this.setState({job: this.state.job});     }       render () {         return <Child onChange={this.setJobState.bind(this)} />     } } 

Child Component

class Child extends React.Component {     constructor (props) {         super(props);      }      render () {         <form>          <input type="text" name="jobNumber" onChange={this.props.onChange} />           <DatePicker name="dateCmmenced" onChange={this.props.onChange}  />         </form>     } } 
like image 756
Han Uman Avatar asked Nov 24 '16 23:11

Han Uman


People also ask

How do you pass onChange to child component React?

To pass an onChange event handler to a child component in React: Define the event handler function in the parent component. Pass it as a prop to the child component, e.g. <Child handleChange={handleChange} /> . Set it to the onChange prop on the input field in the child.

How can I update state of a component in React?

To update our state, we use this. setState() and pass in an object. This object will get merged with the current state. When the state has been updated, our component re-renders automatically.

How can we pass an event handler to the child component?

Just call an alert method in the childToParent function and pass that function as a prop to the child component. And in the child component, accept the childToParent function as a prop. Then assign it to an onClick event on a button. That's it!


2 Answers

The onChange handler for the DatePicker is not called with a standard browser change event, but with value and formattedValue as arguments. I would recommend to register different onChange handlers in your Child component that transform the respective input field's event:

Controller Component

class Parent extends React.Component {     constructor (props) {         super(props);         this.state = {}      }      onChange(field, value) {         // parent class change handler is always called with field name and value         this.setState({[field]: value});     }       render () {         return <Child onChange={this.onChange.bind(this)} />     } } 

Child Component

class Child extends React.Component {     constructor (props) {         super(props);     }      onFieldChange(event) {         // for a regular input field, read field name and value from the event         const fieldName = event.target.name;         const fieldValue = event.target.value;         this.props.onChange(fieldName, fieldValue);     }      onDateChange(dateValue) {         // for a date field, the value is passed into the change handler         this.props.onChange('dateCommenced', dateValue);     }      render () {         return <form>           <input type="text" name="jobNumber" onChange={this.onFieldChange.bind(this)} />            <DatePicker onChange={this.onDateChange.bind(this)}  />         </form>     } } 
like image 184
forrert Avatar answered Oct 14 '22 15:10

forrert


import React from 'react' export default {   [formData, setFormData] = React.useState({     name: '',     number: '',     email: '',     address: '',     zip: ''   })    const handleChange = (e) => {     setFormData({ ...formData, [e.target.name]: e.target.value })   }      return (     <div>       <input type='text' name='name' onChange={handleChange} />       <input type='text' name='number' onChange={handleChange} />       <input type='email' name='email' onChange={handleChange} />       <textarea name='address' onChange={handleChange}></textarea>       <input type='text' name='zip' onChange={handleChange} />     </div>   ) }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
like image 20
Sourav Purkait Avatar answered Oct 14 '22 17:10

Sourav Purkait