Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/408.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ReactJS中选定输入的计数值_Javascript_Reactjs_React Jsx - Fatal编程技术网

Javascript ReactJS中选定输入的计数值

Javascript ReactJS中选定输入的计数值,javascript,reactjs,react-jsx,Javascript,Reactjs,React Jsx,我很难理解/概念化如何在ReactJS中创建组件。我举了一个小例子,在这个例子中,我有一个膳食计划的顶部组件,然后我有另一个组件,用于计划中的每顿饭 现在,我需要一个组件来显示用户选择膳食类别的次数。我在这里举了一个小例子 因此,使用这个示例,我需要一个组件来总结用户当前选择了多少水果和蔬菜。我以前的想法是,我需要在类别更改的某个地方更改计数,但我认为在react中,这应该是不同的,更容易,对吗?这感觉就像我应该(不知怎么的?)抓取类别选择框的值并计算它们,然后在新组件中呈现出来。我觉得我应该看

我很难理解/概念化如何在ReactJS中创建组件。我举了一个小例子,在这个例子中,我有一个膳食计划的顶部组件,然后我有另一个组件,用于计划中的每顿饭

现在,我需要一个组件来显示用户选择膳食类别的次数。我在这里举了一个小例子

因此,使用这个示例,我需要一个组件来总结用户当前选择了多少水果和蔬菜。我以前的想法是,我需要在类别更改的某个地方更改计数,但我认为在react中,这应该是不同的,更容易,对吗?这感觉就像我应该(不知怎么的?)抓取类别选择框的值并计算它们,然后在新组件中呈现出来。我觉得我应该看看ref文档,但它们使用了一个非常简单的示例

我不确定该怎么做

这是代码

JSON

var plan = { 
    "meals": [
      {
        "selectedFood":"",
        "mealName":"breakfast"
      },
      {
        "selectedFood":"",
        "mealName":"lunch"
      },
      {      
        "selectedFood":"",
        "mealName":"dinner"
      },
    ],
    "planOptions": [
      {
        "id":1,
        "category":"fruit",
        "food":"apple"
      },
      {
        "id":2,
        "category":"fruit",
        "food":"pear"
      },
      {
        "id":3,
        "category":"vegetable",
        "food":"carrot"
      },
      {
        "id":4,
        "category":"vegetable",
        "food":"corn"
      }
    ]
};
JSX

var PlanEntryBox = React.createClass({
    getInitialState: function() {
        return {
            plan: {}
        };
    },
    render: function() {
    var planOpts = this.props.plan.planOptions;
    var meals = this.props.plan.meals.map(function(meal) {
            return (
                <MealEntryBox mealEntry={meal} planOptions={planOpts} />
            );
        });
        return (
        <div>
            <h1>Meals</h1>
                <table className="table">
           <thead>
             <tr>
               <th>Meal</th>
               <th>Category</th>
               <th>Food</th>
             </tr>
           </thead>
           <tbody>
             {meals}
           </tbody>
         </table>
         <CategoryCounter />
       </div>
        );
    }
});

var MealEntryBox = React.createClass({
    getInitialState: function() {
        return {
            selectedCategory: null
        };
    },
    categoryChange: function(event) {
        this.setState({selectedCategory: event.target.value});
    },
    render: function() {
        var options = _.uniq(_.pluck(this.props.planOptions, 'category'));
        var categoryOpts = options.map( function(category) {
            return (
                <option>{category}</option>
            );
        });

    var filteredOptions = _.filter(this.props.planOptions, {"category": this.state.selectedCategory});
        var foodOpts = filteredOptions.map( function(option) {
            return (
                <option>{option.food}</option>
            );
        });
        return (
     <tr>
             <td>{this.props.mealEntry.mealName}</td>
       <td>
             <select className="form-control" onChange={this.categoryChange}>
                 <option>Pick one... </option>
         {categoryOpts}
             </select>
       </td>

       <td>
             <select className="form-control" disabled={!this.state.selectedCategory}>
         {foodOpts}
             </select>
       </td>
     </tr>
        );
    }
});


var CategoryCounter = React.createClass({
  render: function() {
    return(
      <div>
        <h3>Counts</h3>
      </div>
    );
  }
});

React.render(
    <PlanEntryBox plan={plan} />,
    document.getElementById('content')
);
var PlanEntryBox=React.createClass({
getInitialState:函数(){
返回{
计划:{}
};
},
render:function(){
var planOpts=this.props.plan.planOpts;
var fines=this.props.plan.fines.map(函数(餐){
返回(
);
});
返回(
餐
一餐
类别
食物
{膳食}
);
}
});
var MealEntryBox=React.createClass({
getInitialState:函数(){
返回{
selectedCategory:空
};
},
类别更改:功能(事件){
this.setState({selectedCategory:event.target.value});
},
render:function(){
var options=u.uniq(u.pull(this.props.planpoptions,'category');
var categoryOpts=options.map(函数(类别){
返回(
{类别}
);
});
var filteredOptions=..filter(this.props.planpoptions,{“category”:this.state.selectedCategory});
var foodOpts=filteredOptions.map(函数(选项){
返回(
{option.food}
);
});
返回(
{this.props.mealEntry.mealName}
挑一个。。。
{categoryOpts}
{foodOpts}
);
}
});
var CategoryCounter=React.createClass({
render:function(){
返回(
计数
);
}
});
反应(
,
document.getElementById('content')
);
HTML

<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.rawgit.com/lodash/lodash/3.0.1/lodash.min.js"></script>
<script src="//fb.me/react-0.13.1.js"></script>
<script src="https://code.jquery.com/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
  <meta charset="utf-8">
  <title>Meal Plan Example</title>
</head>
<body>

  <div id="content">

  </div>

</body>
</html>

膳食计划示例

这是组件
状态的一个相当简单的用法

您需要在父组件中存储水果和蔬菜的计数(
PlanEntryBox
)。首先更新
PlanEntryBox.getInitialState()
,为这些计数器添加字段

getInitialState: function() {
    return {
        plan: {}, 
        fruitCount: 0,
        vegieCount: 0
    };
},
然后,将函数添加到
PlanEntryBox
组件以处理更新计数:

addFruit: function(){
    this.setState({fruitCount: this.state.fruitCount++});
},
addVegie: function(){
    this.setState({vegieCount: this.state.vegieCount++});
}
(您可能还需要减少计数的方法,但我将留给您。)

然后将对这些方法的引用作为道具传递给每个
MealEntryBox
组件。将行
PlanEntryBox
render
功能修改为:

<MealEntryBox mealEntry={meal} planOptions={planOpts}
    onFruit={this.addFruit} onVegie={this.addVegie}/>
(注意:同样,这是一个幼稚的实现。如果用户取消选择膳食或将类型从一个类别更改为另一个类别,则需要处理递减值。)

例如,调用
onFruit
将导致父组件更新其状态(使用
setState()
调用
addFruit()
)。这将导致React渲染组件,并将新道具传递给其子元素。您可以通过将计数传递给
CategoryCounter
组件来利用这一事实

PlanEntryBox
中的主
render()
函数中修改使用
CategoryCounter
的行,如下所示:

<CategoryCounter fruits={this.state.fruitCount} vegies={this.state.vegieCount} />
总结战略:

  • 使用
    状态
    将计数存储在顶级组件中
  • 将回调函数的引用传递给子组件
  • 更新回调方法中的状态
  • 将当前状态作为道具传递给
    类别计数器
    ,以便它可以显示计数
  • 依靠React在状态发生变化时重新渲染组件,这将导致新的道具被传递到
    CategoryCounter
    ,然后,CategoryCounter也会重新渲染和显示其新道具

有关回调和向组件树传递数据的进一步阅读,请参阅React教程的第五步:

如果您觉得我的答案有用,您介意接受吗?
<CategoryCounter fruits={this.state.fruitCount} vegies={this.state.vegieCount} />
render: function() {
    <div>
        <h3>Counts</h3>
        <ul>
          <li>Fruits: {this.props.fruits}</li>
          <li>Vegetables: {this.props.vegies}</li>
        </ul>
    </div>
}