问题
I've recently found a nice solution for a very similar problem but I don't know why it doesn't work in my next example.
What I am trying to do is:
I have created a Component which consists of two input fields, onSubmit of the Form the state, which is an array, of the parent Component should be pushed with the value of the two input fields.
Note The name of the parent Component is "Test". The Name of the component with the input fields ,that should update the parents state is named "CreateDogs".
My code can be seen here: http://jsfiddle.net/69z2wepo/4364/
Also here:
/** @jsx React.DOM **/
// in den root ordner navigieren und : jsx --watch src/ build/ im Terminal ausführen build/ == development ordner src/ == production order
var CreateDogs = React.createClass({
getInitialState: function(){
return{
inputName: 0,
inputWeight: 0
}
},
getName: function(e){
this.setState({
inputName: e.target.value
});
},
getWeight: function(e){
this.setState({
inputWeight: e.target.value
});
},
updateDog: function(){
event.preventDefault();
data = [this.state.inputName, this.state.inputWeight];
this.props.addDog(data);
},
render: function(){
return(
<form onSubmit={this.updateDog}>
<label>Name:<br/>
<input onChange={this.getName} value={this.state.inputName} type="text"/>
</label><br/>
<label>Gewicht:<br/>
<input onChange={this.getWeight} value={this.state.inputWeight} type="text"/>
</label>
<br/>
<input type="submit" value="Hinzufügen"/><br/><br/>
</form>
);
}
});
var Test = React.createClass({
getInitialState: function(){
return{
data: [
['Charlie', 10],
['Bello', 20],
['Balou', 15]
],
active: 0,
meat: 0,
fruit: 0,
veg: 0,
carb: 0,
muscle: 0,
bones: 0,
pansen: 0,
innereien: 0,
pflanzlich: 0
}
},
changeWeight: function(newWeight){
newWeight = newWeight * 1000; // in Gramm
// do whatever actions you want on click here
var calculatedTotal = newWeight * 0.03; // if Dog == active
var calculatedMeat = calculatedTotal * 0.7; // 70% des Tagesbedarfs sind Fleisch
var calculatedMuscle = calculatedMeat * 0.5;
var calculatedBones = calculatedMeat * 0.2;
var calculatedPansen = calculatedMeat * 0.15;
var calculatedInnereien = calculatedMeat * 0.15;
var calculatedPflanzlich = (calculatedTotal * 0.3);
var calculatedVeg = (calculatedTotal * 0.3) * 0.4;
var calculatedFruit = (calculatedTotal * 0.3) * 0.2;
var calculatedCarb = (calculatedTotal * 0.3) * 0.4;
this.setState({
meat: calculatedMeat,
fruit: calculatedFruit,
veg: calculatedVeg,
carb: calculatedCarb,
muscle: calculatedMuscle,
bones: calculatedBones,
pansen: calculatedPansen,
innereien: calculatedInnereien,
pflanzlich: calculatedPflanzlich
});
},
addDog: function(newDog){
console.log('in der addDog Function: '+newDog);
this.setState({
data: this.state.data.push.newDog
});
},
render: function(){
return(
<div>
<CreateDogs addDog={this.addDog} />
<MakePOS data={this.state.data} handleClick={this.changeWeight} />
<MakeTable active={this.state.active} meat={this.state.meat} fruit={this.state.fruit} veg={this.state.veg} carb={this.state.carb} muscle={this.state.muscle} bones={this.state.bones} pansen={this.state.pansen} innereien={this.state.innereien} pflanzlich={this.state.pflanzlich} />
</div>
);
}
});
var MakeTable = React.createClass({
getInitialState: function(){
return{
active: 0
}
},
render: function(){
return(
<div className="diet">
<CreateTable meat={this.props.meat} fruit={this.props.fruit} veg={this.props.veg} carb={this.props.carb} muscle={this.props.muscle} bones={this.props.bones} pansen={this.props.pansen} innereien={this.props.innereien} pflanzlich={this.props.pflanzlich} />
<p>Wöchentliche Einkaufsliste</p>
<CreateTable meat={this.props.meat*7} fruit={this.props.fruit*7} veg={this.props.veg*7} carb={this.props.carb*7} muscle={this.props.muscle*7} bones={this.props.bones*7} pansen={this.props.pansen*7} innereien={this.props.innereien*7} pflanzlich={this.props.pflanzlich*7} />
</div>
);
}
});
var CreateTable = React.createClass({
render: function(){
return(
<table>
<thead>
<tr>
<td>Type</td>
<td>Amount</td>
<td>pro</td>
</tr>
</thead>
<tbody>
<tr>
<td>Tierisch</td>
<td>{this.props.meat} g</td>
<td>Tag</td>
</tr>
<tr>
<td>Beinhalted</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Muskelfleisch</td>
<td>{this.props.muscle} g</td>
<td>Tag</td>
</tr>
<tr>
<td>Fleischige Knochen</td>
<td>{this.props.bones} g</td>
<td>Tag</td>
</tr>
<tr>
<td>Pansen</td>
<td>{this.props.pansen} g</td>
<td>Tag</td>
</tr>
<tr>
<td>Innereien</td>
<td>{this.props.innereien} g</td>
<td>Tag</td>
</tr>
<tr>
<td>Pflanzlich</td>
<td>{this.props.pflanzlich} g</td>
<td>Tag</td>
</tr>
<tr>
<td>Beinhalted</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Gemüse</td>
<td>{this.props.veg} g</td>
<td>Tag</td>
</tr>
<tr>
<td>Obst</td>
<td>{this.props.fruit} g</td>
<td>Tag</td>
</tr>
<tr>
<td>Carb</td>
<td>{this.props.carb} g</td>
<td>Tag</td>
</tr>
</tbody>
</table>
);
}
});
var MakePOS = React.createClass({
handleClick: function(weight){
this.props.handleClick(weight);
},
render: function(){
var POS = this.props.data.map(function(i){
// console.log(i[0]+' '+i[1]+' kg');
return <button onClick={this.handleClick.bind(this,i[1])} key={i[0]} id={i[0]}>{i[0]}</button>;
}.bind(this));
return(<div className="testDiv">{POS}</div>);
}
});
React.render(<Test />, document.getElementById('foodApp'));
I hope you guys know what I mean. THank you
回答1:
I can see 2 problems with your solution,
1. you have a syntax error in the addDog function this.state.data.push.dog
should be this.state.data.push(dog)
. However, this raises the second issue, in the docs they say to treat state as if it were immutable: "NEVER mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable."
There are a few ways to do that:
http://jsfiddle.net/89jo9xq9/
var newDogs = this.state.data.slice();
newDogs.push(dog)
this.setState({
data: newDogs
})
or
http://jsfiddle.net/89jo9xq9/1/
this.setState({
data: this.state.data.concat([dog])
})
来源:https://stackoverflow.com/questions/29131109/update-state-or-parent-component-in-react