我正在使用React&_underscorejs从JSON对象数组中过滤单个数据元素,并将其呈现在表中的屏幕上。我的代码将呈现已过滤的数据,但是几秒钟后,整个表也将呈现。
this.state = { stats:[],
value:'';
componentDidMount() {
fetch('http://localhost:5000/cityStats')
.then((data) => data.json())
.then((data) => this.setState( { stats: data } ))
;
}
// Using a select menu to select value
handleChange = (e) => {
this.setState({ value: e.target.value });
// Filtering a element that matches value choosen
this.setState( { "stats": _.where(this.state.stats,
{NAME:e.target.value})});
this.getDataAgain();
}
//
getDataAgain (){
fetch('http://localhost:5000/citystats')
.then((data) => data.json())
.then((data) => this.setState( { stats: data } ));
}
如果我不调用getDataAgain(),则过滤器将只工作一次并显示空白列表。当用户选择一个选项时,如何解决它以仅显示过滤的数据?
答案 0 :(得分:1)
使用两个数组并调用一次端点,将原始数组保存在两个数组this.setState({ stats: data, filtered: data})
中。使用filtered
数组作为数据源。
state = { stats: [], filtered: [], value: '' };
componentDidMount = () => {
this.getDataAgain();
}
// Using a select menu to select value
handleChange = e => {
this.setState({ value: e.target.value });
// Filtering a element that matches value choosen
const filtered = _.where(this.state.stats, { NAME: e.target.value });
this.setState({
filtered: filtered
});
};
//
getDataAgain = () => {
fetch('http://localhost:5000/citystats')
.then(data => data.json())
.then(data => this.setState({ stats: data, filtered: data }));
}
您当前正在使用stats
的地方,将其更改为this.state.filtered
答案 1 :(得分:0)
这里的主要问题是您正在使用过滤的对象覆盖数据。这绝对是解决该问题的错误方法。将数据设置为状态后,就不应对其进行突变,以避免其他不必要的api请求。
注意:此外,您还应该删除getDataAgain或将其命名为getData,然后在CDM方法中对其进行调用,以避免代码重复。
componentDidMount() {
this.getData();
}
getData() {
fetch('http://localhost:5000/cityStats')
.then((data) => data.json())
.then((stats) => this.setState( { stats } ))
}
方法1:使用私有属性设置/取消设置数据
stats = undefined; // Will permanently hold the whole dataset
componentDidMount() {
fetch('http://localhost:5000/cityStats')
.then(data => data.json())
.then(stats => {
this.stats = stats; // Saves the whole unfiltered dataset to private prop
this.setState({ stats });
});
}
handleChange = e => {
const { value } = e.target.value;
// In case value is unset it will revert stats to the whole unfiltered set
// from the data prop
this.setState({
value,
stats: value ? _.where(this.state.stats, { NAME: value }) : this.stats
});
};
方法2:在渲染中进行过滤(可选的存储方式)
只需在渲染中对其进行过滤。如果您没有庞大的数据集,则不会造成任何性能问题。
render() {
const { stats, value } = this.state;
const filteredData = value
? _.where(stats, { NAME: value })
: stats;
.. do something with filteredData
}
即使在数据集很大的情况下,也应该在render函数中进行过滤,因此始终显示正确过滤的数据。唯一的区别是,在这种情况下,您将使用某种形式的记忆功能,以便每个过滤的集都被缓存以备下一次渲染。
一个基本示例:https://medium.com/@planttheidea/memoize-react-components-33377d7ebb6c