在 React 中过滤 table 的最佳方式
Best way to filter table in React
我有一组对象存储在 redux 中。我希望能够根据用户输入过滤该数组。我应该创建一个通过道具接收数组的状态对象并修改该数组,还是混合状态和道具是不好的做法?如果可以混合使用两者,我是否应该在 componentWillReceiveProps 中设置状态?
基于 props 构建状态可能有些复杂,这是可以接受的,但您应该考虑所有选项。
最简单的实现方式是过滤 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>
);
}
}
下一个选项是执行您所描述的操作,并根据组件的过滤器状态和传递给它的道具派生计算状态。当你有一个复杂的组件接收很多道具并且经常渲染时,这很好。在这里,您正在缓存可视元素,并且仅在需要过滤时才过滤列表。
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>
);
}
}
最后,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>
)
}
我有一组对象存储在 redux 中。我希望能够根据用户输入过滤该数组。我应该创建一个通过道具接收数组的状态对象并修改该数组,还是混合状态和道具是不好的做法?如果可以混合使用两者,我是否应该在 componentWillReceiveProps 中设置状态?
基于 props 构建状态可能有些复杂,这是可以接受的,但您应该考虑所有选项。
最简单的实现方式是过滤 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>
);
}
}
下一个选项是执行您所描述的操作,并根据组件的过滤器状态和传递给它的道具派生计算状态。当你有一个复杂的组件接收很多道具并且经常渲染时,这很好。在这里,您正在缓存可视元素,并且仅在需要过滤时才过滤列表。
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>
);
}
}
最后,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>
)
}