在React中过滤表的最佳方法

Jul*_*szc 13 javascript reactjs redux

我有一个存储在redux中的对象数组.我希望能够根据用户输入过滤该数组.我应该创建一个状态对象,通过道具接收数组并修改该数组,或者混合状态和道具是不好的做法?如果可以将两者混合,我应该在componentWillReceiveProps中设置状态吗?

Nat*_*gen 24

基于道具建立状态可能有点复杂,这是可以接受的,但您应该考虑所有选项.

最简单的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>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

下一个选项是执行您正在描述的内容,并根据组件的过滤器状态和传递给它的props来派生计算状态.当你有一个复杂的组件收到很多道具并经常渲染时,这是很好的.在这里,您将缓存可查看元素,并仅在需要过滤时过滤列表.

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>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

最后,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>
  )
}
Run Code Online (Sandbox Code Playgroud)