Reputation: 1
I'm trying to pass data from a React form in a Child component to a Parent component, but i'm missing something.
When i pass the data from within the parent component only, everything works fine. However i would really like to learn how to use several components.
I'm new to React and i would really appreciate help from someone.
This is my Parent Component:
import React from 'react';
import CalculateIMC from './calculateIMC'
import Results from './results';
import '../css/Form.css';
class App extends React.Component{
constructor(props) {
super(props)
this.state = {
name: "",
height: "",
weight: "",
bmi: "",
};
this.calBmi = this.calBmi.bind(this);
}
calBmi = () => {
const { height, weight } = this.state;
const calcBmi = (weight / (height / 100) ** 2).toFixed(2);
const bmiClass = this.getBmi(calcBmi);
this.setState({isSubmitted: true})
this.setState({
bmi: calcBmi,
bmiClass : bmiClass
})
}
getBmi = (bmi) => {
if(bmi < 18.5) {
return "Underweight";
}
if(bmi >= 18.5 && bmi < 24.9) {
return "Normal weight";
}
if(bmi >= 25 && bmi < 29.9) {
return "Overweight";
}
if(bmi >= 30) {
return "Obesity";
}
}
clearAll = () => {
console.log("test");
this.setState({
name: "",
height: "",
weight: "",
bmi: ""
});
};
render() {
return (
<div className="App">
<CalculateIMC calBmi={this.calBmi}/>
{this.state.isSubmitted && <Results {...this.state}/>}
</div>
);
}
}
export default App
Child component
import React from 'react';
class CalculateIMC extends React.Component{
constructor(props) {
super(props)
this.state = {
name: "",
height: "",
weight: "",
bmi: "",
};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit = (e) => {
e.preventDefault()
this.props.calBmi()
}
render() {
return (
<div className="container">
<form className="card-body" onSubmit={e => this.handleSubmit(e)}>
<div className="field">
<div className="two fields">
<div className="field">
<label>Nom : </label>
<input type="text" required placeholder="Saisir votre nom" value={this.state.name} onChange={e => this.setState({ name: e.target.value })}/>
</div>
<div className="field">
<label>Taille : </label>
<input type="number" required placeholder="Taille en cms" value={this.state.height} onChange={e => this.setState({ height: e.target.value })}/>
</div>
<br />
<div className="field">
<label>Poids : </label>
<input type="number" required placeholder="Poids en Kgs" value={this.state.weight} onChange={e => this.setState({ weight: e.target.value })}/>
</div>
</div>
<button type="submit" className="ui button" tabIndex="1">Calcul</button>
<button className="ui button" tabIndex="0" onClick={this.props.clearAll}>Effacer</button>
</div>
</form>
</div>
)
}
}
export default CalculateIMC
Upvotes: 0
Views: 80
Reputation: 760
You need to update your calBmi() prop to have the form values as a parameter:
parent:
calBmi = (formParameters) => {
// do something with formParameters
}
child:
handleSubmit = (e) => {
e.preventDefault()
this.props.calBmi({
name: this.state.name,
height: this.state.height,
weight: this.state.weight,
}
})
}
I suggest you also change its name calBmi => onFormSubmit
Upvotes: 0
Reputation: 840
You are not passing the child's form data to the parent, instead you are just calling the callback without parameters, that's the problem.
On the child component you should do this (or similar):
handleSubmit = (e) => {
e.preventDefault();
this.props.calBmi(this.state);
}
On the parent:
calBmi = (childFormData) => {
const { height, weight } = childFormData;
const calcBmi = (weight / (height / 100) ** 2).toFixed(2);
const bmiClass = this.getBmi(calcBmi);
this.setState({isSubmitted: true}); // you can merge this setState with below one
this.setState({
bmi: calcBmi,
bmiClass : bmiClass
})
}
Upvotes: 2