在反应中更新状态或父组件

update state or parent component in react

我最近为一个非常相似的问题找到了一个很好的解决方案,但我不知道为什么它在我的下一个示例中不起作用。

我想做的是:

我创建了一个由两个输入字段组成的组件,表单的 onSubmit 应该使用两个输入字段的值推送父组件的状态,它是一个数组。

备注 父组件的名称是 "Test"。具有输入字段的组件的名称应该更新父状态,名称为 "CreateDogs".

我的代码可以在这里看到: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')); 

我希望你们明白我的意思。谢谢

我发现您的解决方案存在 2 个问题, 1. 你在 addDog 函数中有语法错误 this.state.data.push.dog 应该是 this.state.data.push(dog) 。但是,这引发了第二个问题,在 docs 中他们说要将状态视为不可变的:"NEVER mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable."

有几种方法可以做到这一点:

http://jsfiddle.net/89jo9xq9/

var newDogs = this.state.data.slice(); 
newDogs.push(dog) 
this.setState({
  data: newDogs
})

http://jsfiddle.net/89jo9xq9/1/

 this.setState({
  data: this.state.data.concat([dog])
})