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> } }
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.
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.
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!
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> } }
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With