Reputation: 89
I have a CreateTesterModal
class which has a state of location. This class renders a form component that shows up inside this modal class like so:
CreateTesterModal -> CreateTesterForm
When user clicks on Add
Location link then this new modal opens which contains the location form
CreateTesterForm -> AddLocationModal -> AddLocationForm
My question now is how do I update my location state from the main modal (CreateTesterModal
) based on what user will enter in the child component of AddLocationForm
?
I am new to react
and really need this logic to work without using redux
. Can someone please help?
CreateTesterModal:
constructor(props) {
super(props);
this.state = {
fields: {
location: 'No Location Selected',
}
};
}
fieldChange(field, value) {
this.setState(update(this.state, { fields: { [field]: { $set: value } } }));
}
updateLocation(newLocation) {
this.setState({
location: newLocation
})
}
render() {
return (
<div>
...
<div className={`modal-body ${styles['proj-modal-body']}`}>
<CreateTesterCharacteristicForm
fields={this.state.fields}
onChange={this.fieldChange.bind(this)}
onValid={() => handleSubmit(this.state.fields)}
onInvalid={() => console.log('Error!')}
updateLocation={this.updateLocation.bind(this)}
/>
</div>
...
</div>
);
}
CreateTesterForm:
<form>
<div id={styles.locationField} className={`form-group ${styles.formGroup} ${styles.projName}`}>
<label htmlFor="inputEmail3" className="col-sm-2 control-label">Location:</label>
<div className="location">
<label className="radio-inline">
<Link to="#" data-toggle="modal" data-target="#addLocationModal">Add Locations</Link>
</label>
</div>
</div>
</form>
<button
className={`btn btn-primary text-white ${styles.saveBtn}`}
onClick={e => {
e.preventDefault();
this.props.$submit(onValid, onInvalid);
}}
>
Save
</button>
<AddLocationModal />
AddLocationModal:
render() {
return (
<div id="newLocationModal">
<AddLocationForm />
</div>
);
}
AddLocationForm:
constructor(props) {
super(props);
this.state = {
locations: [],
};
}
render() {
return (
<form id="modalForm" className="form-horizontal">
<input
type="text"
class="form-control"
id="location"
/>
<div className={`modal-footer ${styles.modalFooter}`}>
<button className={`btn btn-primary text-white ${styles.saveBtn}`}>
Add More
</button>
<button
type="button"
className={`btn btn-default ${styles.cancelBtn}`}
data-dismiss="modal"
>
Finish
</button>
</div>
</form>
);
}
Upvotes: 1
Views: 719
Reputation: 110
You would have to define a function in the child component that calls another function in the parent component(as props) with the data you want to update.I don't have your code but it should be something like this:
//child component
...class
update = (data) =>{
this.props.Parentupdate(data)
}
//Parentupdate is the function in the parent class that will be passed down as props to the child comp.
//Inside the parent component
update = (data) =>{
this.setState({data etc etc})
}
//When rendering the child component
<Child Parentupdate={this.update}/>
//This is passing the parent function to the child as a prop.
Upvotes: 0
Reputation: 3487
Basically, you can do this by passing a handler from the parent to the child
Attention : Here the handler works fine with
this
because it has been defined as an arrow function. If using the class method syntax, don't forget to bind thethis
of the class to the method orthis
will reference the DOM element triggering the event (in this case, thebutton
)
class Parent extends Component {
state = { location: null }
updateLocation = location => {
this.setState({ location })
}
render () {
return <div><Child updateLocation={this.updateLocation} /></div>
}
}
// Get the updateLocation function as a prop in your child component
const Child = props => {
const { updateLocation } = props
return <button onClick={() => updateLocation('someLocation')}>Some Location</button>
}
Upvotes: 1