通过过滤器属性父组件

问题描述 投票:1回答:1

我三个部分组成。

  1. 项目清单
  2. 过滤器部件

父进程得到通过Redux的状态时,它的数据:

Parent

const mappedEvents =
  events.length === 0 ? (
    <p style={{ textAlign: 'center' }}>Det finns inte några händelser</p>
  ) : (
    events.reverse().map((event, i) => {
      var driver = event.driver ? keyedDrivers[event.driver] : false
      var carrier = driver ? keyedCarriers[driver.carrier] : false
      var customer = event.customer ? keyedCustomers[event.customer] : false

      return (
        <div>
          <EventItem // This is a list item
            key={i}
            event={event}
            customer={customer}
            carrier={carrier}
            driver={driver}
            lock={keyedLocks[event.unit] || { address: {} }}
          />
        </div>
      )
    })
  )

然后return里面我显示出来,如:

<Grid>{mappedEvents}</Grid>这给了我一个名单,

但我希望能够对其进行过滤。所以,我创建了一个过滤器组件,它也可以通过Redux的状态得到它的数据。

Filter Component

  constructor(props) {
    super(props)
    this.state = {
      filteredEvents: ''
    }
  }

  toggle(event) {
    this.setState({ filteredEvents: event.target.value })
  }
  ...

const organizationList = carriers
  .filter(
    carrier =>
      !this.state.filteredEvents ||
      carrier.organization.indexOf(this.state.filteredEvents) >= 0
  )
  .map(carrier => (
    <div>
      <input
        type="checkbox"
        value={carrier.organization}
        onChange={this.toggle.bind(this)}
      />
      <MenuItem eventKey={carrier.id} key={carrier.id}>
        {carrier.organization}
      </MenuItem>
    </div>
  ))

这使得物联网的用户可以检查列表:

然而,当我点击其中一个复选框就开始复选框的滤镜阵列:

所以,我不知道如何可以通过过滤器部件,所以我可以开始过滤EventItem阵列。我应该开始做减速,使过滤还是应该过滤器组件调用回调回父和父呈现过滤列表?

javascript reactjs filter redux
1个回答
1
投票

基本上你要保持你的过滤器状态的终极版商店。你的过滤器应该派遣一个更新状态的动作,然后当渲染列表,你会不会有过滤。

events.filter((event) => {
  // filter based on redux state
}).reverse().map((event, i) => {

--

toggle(event) {
  // this.setState({ filteredEvents: event.target.value })
  // dispatch an action that updates the redux state filters here
}

多一点信息

我将过滤器可能存储为布尔值。减速机的初始状态会是这个样子(或者你可以有事件/过滤器分离减速):

events: [],
filters: {
  qlocx: false,
  best: false,
  bring: false // etc..
}

更新筛选器操作将设置对应的复选框过滤器布尔。

在你mapStateToProps你会同时拥有eventsfilters

然后在你的渲染功能,您可以使用.filter过滤根据您的过滤器状态的事件。

你可以使用像重新选择缓存过滤列表,但有一个小清单,你不应该看到从一个单一的过滤功能的任何性能问题。

// inside the render function, filter the array based on filters set
// just a simple render function example for demonstration
render() {
  return (
    <div>
      {events
        .filter((event) => {
          // filter based on redux state
          if (event.qlocx && filters.qlocx) {
            return true;
          }
          // etc..

          // filter any that don't match (might want to return true if no filters are set)
          return false;
        })
        .reverse()
        .map((event, i) => {

演示

这里有一个小的演示,但没有终极版。它使用的setState作为派遣行动的替代品,穿过状态下的道具,而不是使用mapStateToProps

class Filters extends React.Component {
  onUpdateFilter = (event) => {
    // event.target is the input that you changed, so you can get the name and checked properties
    this.props.updateFilters(event.target.name, event.target.checked);
  }
  
  render() {
    const {
      filters
    } = this.props;

    return (
      <div>
        <input type="checkbox" name="one" onChange={this.onUpdateFilter} value={filters.one} />
        <input type="checkbox" name="two" onChange={this.onUpdateFilter} value={filters.two} />
        <input type="checkbox" name="three" onChange={this.onUpdateFilter} value={filters.three} />
      </div>
    );
  }
}

class List extends React.Component {
  // this would be your reducer's `initialState`
  state = {
    filters: {}
  };
  
  // this code would be in your reducer, and you'd just dispatch an action here
  updateFilters = (name, value) => {
    this.setState({
      filters: {
        // this just makes a copy of state.filters and sets state.filters[name] = value
        ...this.state.filters,
        [name]: value
      }
    });
  }

  render() {
    // both filters and items would come from mapStateToProps
    const {filters} = this.state;
    const {items} = this.props;

    return (
      <div>
        <pre>filters = {JSON.stringify(filters)}</pre>
        <Filters
          filters={filters}
          updateFilters={this.updateFilters}
        />
        <ul>
          {this.props.items
            .filter((item) => {
              if (filters.one && !item.one) {
                return false;
              }
              if (filters.two && !item.two) {
                return false;
              }
              if (filters.three && !item.three) {
                return false;
              }
              
              return true;
            })
            .map((item) => (
              <li key={item.name}>{item.name}</li>
            ))
          }
        </ul>
      </div>
    );
  }
}

// this list would come from your reducer via mapStateToProps
const listItems = [
  {name: 'Item 1', one: true},
  {name: 'Another item 1', one: true},
  {name: 'Item 2', two: true},
  {name: 'Item 2,1', one: true, two: true},
  {name: 'Item 2,3', two: true, three: true},
  {name: 'Item 3', three: true}
];

ReactDOM.render(
  <List items={listItems} />,
  document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<div id="app"></div>
© www.soinside.com 2019 - 2024. All rights reserved.