我正在构建一个具有过滤功能的React应用程序,但这不是问题所在,我想在直接处理过滤之前我必须按照自己的方式进行操作。我已经看了https://facebook.github.io/react/tips/expose-component-functions.html并使用了我对它的理解,但现在我不再确定错误或从何处开始。
我有一个FilterContainer(父)组件,它呈现Filter(子)组件。每个过滤器组件都是一个过滤器列表,这使得我必须在父项而不是子项中执行此功能,因为过滤器是彼此独立的。
当用户点击其中一个过滤器时,我想将点击的元素的值存储到数组中,然后使用该数组过滤掉应该显示的公寓。我的Javascript知识有限,所以我似乎无法自己解决这个问题。
现在,当我点击其中一个Filter按钮时,没有任何反应,并且console.log没有输出任何有意义的内容。
这是过滤器(子)组件
var Filter = React.createClass({
getDefaultProps() {
return {
filterList: [],
name: '',
id: '',
props: []
};
},
render() {
return (
<div id={this.props.id} className="filterCloud quarter-section">
<h3>{this.props.name}</h3>
<ul>
{this.props.filterList.map(function(listValue, i) {
return <li onClick={this.props.onClick} key={i}> {listValue} </li>;
}.bind(this))}
</ul>
</div>
)
}
});
&#13;
这是FilterContainer(父)组件
const FilterContainer = React.createClass({
getInitialState() {
return {
selected: [] /* Holds the filters the user clicked, needs to get updated every time a filter is interacted with */
};
},
handleClick(i) {
this.setState({ clicked: i });
var index = this.state.selected.indexOf(i);
if (index === -1) {
this.state.selected.push(i);
} else {
this.state.selected.splice(index, 1);
}
console.log(this.state);
},
render () {
var filters = []; {/* Doesnt filter any apartments to display them on initial load */}
var boundClick = this.handleClick;
return (
<section id="filterContainer" className="container">
<Filter
onClick={boundClick}
id="kvartFilter"
name={'Kvart'}
filterList={[
'Šubićevac', 'Meterize', 'Baldekin', 'Vidici', 'Rokići', 'Grad'
]} />
<Filter
onClick={boundClick}
id="cijenaFilter"
name={'Cijena'}
filterList={[
'< 600kn', '600kn - 700kn', '700kn - 800kn', '800kn - 900kn', '> 900kn'
]} />
<Filter
onClick={boundClick}
id="osobeFilter"
name={'Broj osoba'}
filterList={[
'1', '2', '3', '4', '5', '6'
]} />
<Filter
onClick={boundClick}
id="kvadraturaFilter"
name={'Kvadratura'}
filterList={[
'40m - 60m', '60m - 70m', '70m - 80m', '> 80m'
]} />
</section>
)
}
});
&#13;
答案 0 :(得分:1)
在@ oliv37的帮助下,我正在回答我自己的问题以供将来参考。
所做的更改:
var boundClick = this.handleClick;
onClick={boundClick}
编辑为onClick={this.handleClick}
this.setState({ clicked: i });
,是多余的return <li onClick = {() => {this.props.onClick(listValue)}} key={i}> {listValue} </li>;
以下是更新的组件
过滤组件
var Filter = React.createClass({
getDefaultProps() {
return {
filterList: [],
name: '',
id: '',
props: []
};
},
render() {
return (
<div id={this.props.id} className="filterCloud quarter-section">
<h3>{this.props.name}</h3>
<ul>
{this.props.filterList.map(function(listValue, i) {
return <li onClick = {() => {this.props.onClick(listValue)}} key={i}> {listValue} </li>;
}.bind(this))}
</ul>
</div>
)
}
});
FilterContainer组件
const FilterContainer = React.createClass({
getInitialState() {
return {
selected: [] /* Holds the filters the user clicked, needs to get updated every time a filter is interacted with */
};
},
handleClick(filterValue) {
var index = this.state.selected.indexOf(filterValue);
if (index === -1) {
this.state.selected.push(filterValue);
} else {
this.state.selected.splice(index, filterValue);
}
console.log(this.state);
},
render () {
var filters = []; {/* Doesnt filter any apartments to display them on initial load */}
return (
<section id="filterContainer" className="container">
<Filter
onClick={this.handleClick}
id="kvartFilter"
name={'Kvart'}
filterList={[
'Šubićevac', 'Meterize', 'Baldekin', 'Vidici', 'Rokići', 'Grad'
]} />
<Filter
onClick={this.handleClick}
id="cijenaFilter"
name={'Cijena'}
filterList={[
'< 600kn', '600kn - 700kn', '700kn - 800kn', '800kn - 900kn', '> 900kn'
]} />
<Filter
onClick={this.handleClick}
id="osobeFilter"
name={'Broj osoba'}
filterList={[
'1', '2', '3', '4', '5', '6'
]} />
<Filter
onClick={this.handleClick}
id="kvadraturaFilter"
name={'Kvadratura'}
filterList={[
'40m - 60m', '60m - 70m', '70m - 80m', '> 80m'
]} />
</section>
)
}
});
答案 1 :(得分:0)
这里有很多话要说。
首先,设置clicked
状态属性,但之前没有定义它,也没有在之后使用它。
其次,您通过直接在handleClick
上调用slice
和push
来直接改变state
方法中的状态。
第三,setState()
是异步的,不要指望立即应用更改(console.log
语句不会显示您所期望的内容。)
请看下面的工作片段:
const FilterContainer = React.createClass({
getInitialState() {
return {
selected: [] /* Holds the filters the user clicked, needs to get updated every time a filter is interacted with */
};
},
handleClick(name) {
var index = this.state.selected.indexOf(name);
this.setState(function(state) {
var selected = index === -1 ? (
state.selected.concat([name])
) : (
state.selected.filter(function(filter, i) { return index !== i })
);
return {
selected: selected
}
});
},
render () {
console.log(this.state);
var filters = []; {/* Doesnt filter any apartments to display them on initial load */}
return (
<section id="filterContainer" className="container">
<Filter
onClick={this.handleClick}
id="kvartFilter"
name={'Kvart'}
filterList={[
'Šubićevac', 'Meterize', 'Baldekin', 'Vidici', 'Rokići', 'Grad'
]} />
<Filter
onClick={this.handleClick}
id="cijenaFilter"
name={'Cijena'}
filterList={[
'< 600kn', '600kn - 700kn', '700kn - 800kn', '800kn - 900kn', '> 900kn'
]} />
<Filter
onClick={this.handleClick}
id="osobeFilter"
name={'Broj osoba'}
filterList={[
'1', '2', '3', '4', '5', '6'
]} />
<Filter
onClick={this.handleClick}
id="kvadraturaFilter"
name={'Kvadratura'}
filterList={[
'40m - 60m', '60m - 70m', '70m - 80m', '> 80m'
]} />
</section>
)
}
});
var Filter = React.createClass({
getDefaultProps() {
return {
filterList: [],
name: '',
id: '',
props: []
};
},
render() {
return (
<div id={this.props.id} className="filterCloud quarter-section">
<h3>{this.props.name}</h3>
<ul>
{this.props.filterList.map(function(listValue, i) {
return <li onClick={() => this.props.onClick(listValue)} key={i}> {listValue} </li>;
}.bind(this))}
</ul>
</div>
)
}
});
ReactDOM.render(<FilterContainer/>,document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
BONUS:您不应该将索引用作key
,因为如果您更改了可能的过滤器数量(可能通过某种方面搜索),那么反应将会遇到这些键并且无法协调某些DOM元素正确,最终难以找到错误。