我有一组来自api的结果,它们以状态“结果”存储在状态中。 我想要状态中的第二个数组“ visible_results”。这应该是“结果”的子集。我正在尝试这样做:
export default class SearchScreen extends Component {
constructor(props) {
super(props);
this.state = {
results: null,
visible_results: null,
low_price: null,
high_price: null,
min_price: null,
max_price: null
};
}
componentDidMount() {
const apiUrl = 'foo';
fetch(apiUrl)
.then(response => response.json())
.then(response => {
this.setState({
results: response.results,
min_price: 1,
max_price: 100
});
this.setState({
low_price: this.state.min_price,
high_price: this.state.max_price
});
});
}
handleChange = event => {
const { name, value } = event.target;
this.setState({
[name]: +value
});
this.setState({
visible_results: this.state.results.reduce((items, x) => {
if (this.state.low_price <= x.price && x.price <= this.state.high_price)
items.push(x);
return items;
})
});
};
handleChange与两个滑块相关,一个滑块设置low_price,另一个滑块设置high_price。然后,函数应该根据low_price或high_price的新值生成results
的子集,并将其保存为状态visible_results
。
没用没有错误,但是visible_results始终为“ null”。滑块肯定可以工作。我尝试用if (1==1)
替换if语句,以确保它不仅仅是if语句的错字。它做同样的事情。
答案 0 :(得分:0)
几件事:
将值设置为null
会使您的代码更复杂,我可以添加一个有用的默认值,例如min_price: 0, max_price: Infinity
或只是不初始化它。
this.setState
是异步的!如果您拨打两次setState
,则第一个通话将被推迟,因此第二次通话中this.state
尚未更新,例如this.state.low_price
中第二个通话中的handleChange
尚未更新。
如果不将初始值传递给reduce
,它将采用数组的第一个元素(在您的情况下是一个对象),对此调用push
无效。您可能想要.reduce(fn, [])
,但实际上.filter
更合适。
visible_results不必是状态的一部分,因为它是由其他状态道具确定的,因此只需在render
代码:
export default class SearchScreen extends Component {
constructor(props) {
super(props);
this.state = {
results: [],
low_price: 0,
high_price: Infinity,
min_price: 0,
max_price: Infinity
};
}
componentDidMount() {
const apiUrl = 'foo';
fetch(apiUrl)
.then(response => response.json())
.then(response => {
this.setState({
results: response.results,
min_price: 1,
max_price: 100,
min_price: 1,
high_price: 100,
});
});
}
handleChange = event => {
const { name, value } = event.target;
this.setState({
[name]: +value
});
}
render() {
const { results, low_price, high_price } = this.state;
const visibleResults = results.filter(item =>
low_price <= item.price && item.price <= high_price);
//...
}
}