Javascript 在 React 中过滤表格的最佳方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35582978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best way to filter table in React
提问by Juliuszc
I have an array of objects stored in redux. I want to be able to filter that array based on user input. Should I create a state object that receives the array through props and modify that array, or is it bad practice to mix state and props? If it is alright to mix the two, should I set the state in componentWillReceiveProps?
我有一个存储在 redux 中的对象数组。我希望能够根据用户输入过滤该数组。我应该创建一个通过 props 接收数组并修改该数组的 state 对象,还是混合 state 和 props 是不好的做法?如果可以将两者混合使用,我应该在 componentWillReceiveProps 中设置状态吗?
回答by Nathan Hagen
Building state based on props can be somewhat complicated, which is acceptable, but you should consider all of your options.
基于 props 构建状态可能有些复杂,这是可以接受的,但您应该考虑所有选项。
The simplest to implement is to filter the props in your render
method. If you have sufficiently small components which don't update for too many reasons, and especially if the number of elements in the list is low, this might be the preferred method:
最简单的实现是过滤你的render
方法中的道具。如果您有足够小的组件由于太多原因不会更新,特别是如果列表中的元素数量很少,这可能是首选方法:
class FilterList extends React.Component {
render () {
const { elements } = this.props;
const { filterStr } = this.state;
const filteredElements = elements
.filter(e => e.includes(filterStr))
.map(e => <li>{ e }</li>)
return (
<div>
<input
type="text"
value={ filterStr }
onChange={ e => this.setState({ filterStr: e.target.value }) } />
<ul>
{ filteredElements }
</ul>
</div>
);
}
}
The next option is to do what you're describing, and derive a computed state based of the component's filter state and props passed to it. This is good when you have a complicated component which recieves many props and is rendered often. Here, you're caching the viewable elements and only filtering the list when it needs to be filtered.
下一个选项是执行您所描述的操作,并根据组件的过滤器状态和传递给它的道具派生计算状态。当您有一个复杂的组件接收许多道具并且经常渲染时,这很好。在这里,您正在缓存可见元素,并且仅在需要过滤时才过滤列表。
class FilterList extends React.Component {
constructor (props) {
this.state = {
viewableEls: props.elements
}
}
componentWillReceiveProps (nextProps) {
const { elements } = this.props;
const { filterStr } = this.state;
if (elements !== nextProps.elements) {
this.setState({
viewableEls: this.getViewableEls(nextProps.elements, filterStr)
})
}
}
getViewableEls (elements, filterStr) {
return elements.filter(el => el.includes(filterStr))
}
handleFilterChange = e => {
const { elements } = this.props;
this.setState({
filterStr: e.target.value,
viewableEls: this.getViewableEls(elements, filterStr)
})
}
render () {
const { viewableEls } = this.state;
return (
<div>
<input
type="text"
value={ filterStr }
onChange={ this.handleFilterChange } />
<ul>
{ viewableEls.map(e => <li key={ e }>{ e }</li>) }
</ul>
</div>
);
}
}
And finally, the redux 'way', which requires you to pass the action creator and filterStr
as props to the component, probably passed in via connect
somewhere else. The implementation below is using a stateless component since we're not keeping the fitlerStr
in the component state at all.
最后,redux 'way',它要求您将动作创建者和filterStr
作为道具传递给组件,可能是通过connect
其他地方传入的。下面的实现使用了一个无状态组件,因为我们根本没有保持fitlerStr
组件状态。
const FilterTable = ({ elements, filterStr, changeFilterStr }) => {
return (
<div>
<input
type="text"
value={ filterStr }
onChange={ e => changeFilterStr(e.target.value) } />
<ul>
{
elements
.filter(e => e.includes(filterStr))
.map(e => <li key={ e }>{ e }</li>)
}
</ul>
</div>
)
}