我尝试创建/原型化具有搜索过滤器的小部件和具有键值/父子关系的2小组。右侧面板包含类别,左侧面板具有与单个类别相关联的兴趣。可以选择类别行以显示关联的兴趣复选框。我还没有尝试理解如何使用复选框更新表单提交,首先我需要了解有关正确的数据流方式的更多信息。
这是我第一次涉足React,我知道React鼓励单向数据流。我觉得我通过使用jQuery处理事件错误地更新了兴趣小组。我想知道更新兴趣小组的一些替代方法。
根据我的阅读,为了更新父级(我相信它在React docs中称为所有者)组件,您需要在子/ ownee组件上定义回调。我很欣赏对此的解释,如果我错误地使用了州与道具的兴趣。我试图只有搜索过滤器&复选框是小部件状态的一部分,因为我读到可过滤的数据应属于道具。
更新:我在getDefaultProps中更改了要初始化的兴趣,所以现在我将它们用作道具。我认为这更像是React方式,我是否正确?我还通过更改handleCategoryRowClick函数来更改兴趣更新的方式。我觉得我现在做的事情反应更多,但是仍然会喜欢任何有更多使用React经验的人给出的建议,谢谢。
非常感谢任何帮助!
/** @jsx React.DOM */
var InterestRow = React.createClass({
render: function() {
return (
<div>
<label>{this.props.interest.name}</label>
<input type="checkbox" ref={this.props.key} value={this.props.key} />
</div>
)
}
});
var InterestPanel = React.createClass({
var interestPanel = this;
var rows = [];
render: function() {
var rows = [];
var i = 0;
_(this.props.interests).each(function (interest) {
rows.push(<InterestRow interest={interest} key={interest.value} />);
});
return (
<form>{rows}</form>
)
}
});
var CategoryRow = React.createClass({
render: function() {
return (
<li onClick={this.props.handleClick.bind(null, this.props.interests)}>{this.props.category}</li>
)
}
});
var CategoriesPanel = React.createClass({
render: function() {
var categoriesPanel = this;
var rows = [];
var categories = [];
var interests = [];
var interestSet = [];
var missedSet = [];
var lastCategory = null;
var category;
var interest;
var i = 0;
_.each(categoriesPanel.props.data, function (datum) {
name = datum.name;
value = datum.targeting_value;
category = name.split('/')[0];
interest = {name: name.split('/')[1], value: value}
if (_.contains(interest.name.toLowerCase(), categoriesPanel.props.searchText.toLowerCase())) {
if (category !== lastCategory) {
if (interestSet.length > 0) {
interests.push(interestSet.concat(missedSet));
}
lastCategory = category;
categories.push(category);
interestSet = [];
interestSet.push(interest);
missedSet = [];
} else {
if (!_.contains(categories, category)) {
categories.push(category);
interestSet.push(interest);
} else {
interestSet.push(interest);
}
}
} else {
if (category !== lastCategory) {
if (interestSet.length > 0) {
interests.push(interestSet.concat(missedSet));
}
lastCategory = category;
interestSet = [];
missedSet = [];
missedSet.push(interest);
} else {
missedSet.push(interest);
}
}
});
if (interestSet.length > 0) {
interests.push(interestSet.concat(missedSet));
}
var interestsObject = _.zipObject(categories, interests);
_.each(interestsObject, function (interestSet, category) {
i++;
rows.push(<CategoryRow category={category} key={i} interests={interestSet} handleClick={categoriesPanel.props.handleClick} />)
});
return (
<div>
<ul>{rows}</ul>
</div>
)
}
});
var SearchBar = React.createClass({
handleChange: function() {
this.props.onUserInput(
this.refs.searchTextInput.getDOMNode().value
)
},
render: function() {
return (
<form onSubmit={this.handleSubmit}>
<input
type="text"
placeholder="Search Interests..."
value={this.props.searchText}
ref="searchTextInput"
onChange={this.handleChange}
/>
</form>
);
}
});
var InterestsTable = React.createClass({
loadDataFromTwitter: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
success: function(data) {
this.setProps({data: data});
}.bind(this)
});
},
getInitialState: function() {
return {
searchText: ''
}
},
getDefaultProps: function() {
return {
data: [],
interests: []
}
},
componentWillMount: function() {
this.loadDataFromTwitter();
},
handleUserInput: function(searchText) {
this.setState({
searchText: searchText
});
},
handleCategoryRowClick: function(interests) {
this.setProps({
interests: interests
});
},
render: function() {
return (
<div>
<SearchBar
searchText={this.state.searchText}
onUserInput={this.handleUserInput}
/>
<CategoriesPanel
data={this.props.data}
searchText={this.state.searchText}
handleClick={this.handleCategoryRowClick}
/>
<InterestsPanel
interests={this.props.interests}
searchText={this.state.searchText}
/>
</div>
);
}
});
React.renderComponent(
<InterestsTable url="/api/interests" />,
document.getElementById('content')
);
答案 0 :(得分:9)
componentDidMount: function() {
$(document).on("handleCategoryRowClick", this.handleCategoryRowClick);
},
props
视为不可变的并且反应生命
循环方法将按预期工作。在这种情况下,interests
应该是
state
代替props
,因为InterestsTable
组件拥有
并修改它;它没有被组件的父母传递: getInitialState: function() {
return {
interests: [],
searchText: ""
};
},
handleCategoryRowClick: function(e, interests) {
this.setState({
interests: interests
});
},