我在查找/概念化如何在ReactJS中创建组件时遇到了麻烦。我把一个小例子放在一起,我有一个膳食计划的顶级组成部分,然后我有另一个组件,用于计划中的每餐。
现在,我想要一个组件,显示用户选择餐饮类别的次数。我在这里掀起了一个小例子。 Meal Plan Example
因此,使用该示例,我想要一个总结用户当前选择的水果和蔬菜数量的组件。我以前的思维方式是,我需要在类别更改的某个地方更改计数,但我认为这应该是不同的,更容易对吗?感觉就像我应该(不知何故?)抓住类别选择框的值并计算它们并在新组件中呈现出来。感觉好像我应该看一下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')
);
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>
答案 0 :(得分:3)
这是对组件state
的相当直接的使用。
您希望在父组件中存储水果计数和蔬菜计数(在您的情况下为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
组件和props。将第PlanEntryBox
行render
行修改为:
<MealEntryBox mealEntry={meal} planOptions={planOpts}
onFruit={this.addFruit} onVegie={this.addVegie}/>
然后使用onFruit
中的onVegie
和MealEntryBox.categoryChange
回调:
categoryChange: function(event) {
if(event.target.value === 'fruit'){
this.props.onFruit();
} else {
this.props.onVegie();
}
this.setState({selectedCategory: event.target.value});
},
(注意:同样,这是一个天真的实现。如果用户取消选择用餐或将类型从一个类别更改为另一个类别,您将需要处理递减值。)
例如,调用onFruit
将导致父组件更新其状态(使用setState()
中的addFruit()
调用)。这将导致React呈现组件,并将新的props传递给其子元素。您可以通过将计数传递给CategoryCounter
组件来利用这一事实。
修改CategoryCounter
中render()
主PlanEntryBox
函数中使用<CategoryCounter fruits={this.state.fruitCount} vegies={this.state.vegieCount} />
的行,如下所示:
CategoryCounter
然后在render: function() {
<div>
<h3>Counts</h3>
<ul>
<li>Fruits: {this.props.fruits}</li>
<li>Vegetables: {this.props.vegies}</li>
</ul>
</div>
}
的渲染方法中,显示这些新道具:
state
总结策略:
CategoryCounter
在顶级组件中存储计数CategoryCounter
,以便它可以显示计数1.Obtain transaction specific information.
2.Obtain your paypal account balance
3.Search your transaction specific information.
4.Search your transactions for items that match specific criteria and display the results
,然后重新渲染并显示其新的道具。要进一步阅读Callbacks并传递数据 up 组件树,请参阅React Tutorial的第五步:https://facebook.github.io/react/docs/thinking-in-react.html#step-5-add-inverse-data-flow