在React中过滤状态而不删除数据

时间:2019-01-13 16:36:03

标签: javascript reactjs

我正在尝试制作一个react组件,该组件可以根据从下拉框中选择的值来过滤列表。由于setState从数组中删除了所有数据,因此我只能过滤一次。如何过滤数据并仍然保持原始状态?我希望能够进行一次搜索即可。

数组列表:

  state = {
tree: [
  {
    id: '1',
    fileType: 'Document',
    files: [
        {
          name: 'test1',
          size: '64kb'
        },
        {
          name: 'test2',
          size: '94kb'
        }
    ]
  }, ..... and so on

我有2种方法可以过滤一次组件:

  filterDoc = (selectedType) => {
   //way #1
   this.setState({ tree: this.state.tree.filter(item => item.fileType === selectedType) })

  //way#2
  const myItems = this.state.tree;
  const newArray = myItems.filter(item => item.fileType === selectedType)
  this.setState({
    tree: newArray
  })      
}

搜索组件:

class SearchBar extends Component {

  change = (e) => {
    this.props.filterTree(e.target.value);
  }

  render() {
      return (
        <div className="col-sm-12" style={style}>
            <input
            className="col-sm-8"
            type="text"
            placeholder="Search..."
            style={inputs}
            />
            <select
            className="col-sm-4"
            style={inputs}
            onChange={this.change}
            >
                <option value="All">All</option>
              {this.props.docTypes.map((type) =>
                <option
                  value={type.fileType}
                  key={type.fileType}>{type.fileType}
                </option>)}
            </select>
        </div>
      )
  }
}

还有一些图像只是为了直观地了解问题。 过滤前: enter image description here

过滤后,所有不匹配的内容都将从状态中删除:

enter image description here

2 个答案:

答案 0 :(得分:1)

请勿替换原始数据

相反,更改使用的过滤器并在render()函数中进行过滤。

在下面的示例中,原始数据(称为data)从未更改。仅更改使用的过滤器。

const data = [
  {
    id: 1,
    text: 'one',
  },
  {
    id: 2,
    text: 'two',
  },
  {
    id: 3,
    text: 'three',
  },
]

class Example extends React.Component {
  constructor() {
    super()
    this.state = {
      filter: null,
    }
  }

  render() {
    const filter = this.state.filter
    const dataToShow = filter
      ? data.filter(d => d.id === filter)
      : data

    return (
      <div>
        {dataToShow.map(d => <span key={d.id}> {d.text}, </span>)}
        <button
          onClick={() =>
            this.setState({
              filter: 2,
            })
          }
        >
          {' '}
          Filter{' '}
        </button>
      </div>
    )
  }
}

ReactDOM.render(<Example />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<body>
  <div id='root' />
</body>

答案 1 :(得分:0)

不要更改本地状态以反映过滤器的当前状态。该状态应反映完整的可用列表,仅在选项列表更改时才应更改。严格将过滤后的数组用于视图。更改显示给用户的内容就应该是这样的事情。

change = (e) => {
   return this.state.tree.filter(item => item.fileType === e.target.value)
}