使反应中的过滤器表失败

时间:2017-12-15 12:46:45

标签: javascript reactjs ecmascript-6

我能够使过滤器工作,但只是使用es6的过滤器,但问题是我不知道如何将状态重置回原始源。

通常数据源是API调用,但是当用户从过滤器输入中删除值时,可以避免api调用吗?

const data = [
  {
    Id: "1",
    FirstName: "Luke",
    LastName: "Skywalker"
  },
  {
    Id: "2",
    FirstName: "Darth",
    LastName: "Vader"
  },
  {
    Id: "3",
    FirstName: "Leia",
    LastName: "Organa"
  },
  {
    Id: "4",
    FirstName: "Owen",
    LastName: "Lars"
  }
];


class App extends React.Component {

  constructor() {
    super()
    this.state = {
      data: data
    }
  }

  filterId(e) {
    const Id = e.target.value
    if (Id) {
      this.setState({
        data: this.state.data.filter(v => v.Id === Id),
      })
    } else {
      this.setState({
        data
      })
    }
  }

  render() {
    return (
      <div style={styles}>
        <table>
          <th>Id <input type="number" onChange={e => this.filterId(e)} /></th>
          <th>Name<input /></th>
          {this.state.data.map((o, i) => {
            return (
              <tr>
                <td>{o.Id}</td>
                <td>{o.FirstName}</td>
              </tr>
            )
          })}
        </table>
      </div>
    );
  }
}

https://codesandbox.io/s/oo22451v25

3 个答案:

答案 0 :(得分:0)

您可以将过滤后的数据存储在单独的变量中,也可以在render函数中动态进行数据过滤,例如this.state.data.filter(v => v.Id === this.state.Id).map(...)

答案 1 :(得分:0)

您可以做几件事,但我建议不要更改状态中存储的原始数据,而是添加一个新的状态属性,该属性在过滤原始数据时保存数据。

然后,您可以将此新状态对象分配给变量并以这种方式输出。

然后它可能看起来像这样:

const data = [
  {
    id: '1',
    firstName: 'Luke',
    LastName: 'Skywalker',
  },
  {
    id: '2',
    firstName: 'Darth',
    LastName: 'Vader',
  },
  {
    id: '3',
    firstName: 'Leia',
    LastName: 'Organa',
  },
  {
    id: '4',
    firstName: 'Owen',
    LastName: 'Lars',
  },
];

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      data: data,
      filteredData: null,
    };

    this.filterId = this.filterId.bind(this);
  }

  filterId(e) {
    const id = e.target.value;
    if (id) {
      this.setState({
        filteredData: this.state.data.filter(v => v.id === id),
      });
    } else {
      this.setState({
        filteredData: null,
      });
    }
  }

  render() {
    const dataOutput = this.state.filteredData || this.state.data;
    return (
      <div>
        <table>
          <th>
            id <input type="number" onChange={e => this.filterId(e)} />
          </th>
          <th>
            Name<input />
          </th>
          {dataOutput.map((o, i) => {
            return (
              <tr key={o.id}>
                <td>{o.id}</td>
                <td>{o.firstName}</td>
              </tr>
            );
          })}
        </table>
      </div>
    );
  }
}

哦,还有一件事:使用camelCase。开头的大写字母只应在声明类时使用。

答案 2 :(得分:0)

首先:您可能希望使用includes()进行过滤以获得可用性。否则,在它们完全相同之前,事情就不会匹配。一旦你开始处理超过一位数的字段,这就很重要。

其次:通过render()方法进行过滤将允许您更加健壮地搜索,即允许您退回到未过滤,因为this.state.data将保持原始状态。

请参阅下面的实例。

// Data.
const data = [
  {
    Id: "1",
    FirstName: "Luke",
    LastName: "Skywalker"
  },
  {
    Id: "2",
    FirstName: "Darth",
    LastName: "Vader"
  },
  {
    Id: "3",
    FirstName: "Leia",
    LastName: "Organa"
  },
  {
    Id: "4",
    FirstName: "Owen",
    LastName: "Lars"
  }
]

// Filter.
class Filter extends React.Component {

  // Constructor.
  constructor(props) {
    super(props)
    this.state = {data, query: ''}
  }

  // Render.
  render() {
    return (
      <div>
        <table>

          <tr>
            <input placeholder="Query" type="number" value={this.state.query} onChange={event => this.setState({query: event.target.value})} />
          </tr>

          <th>Id</th>
          <th>Name</th>

          {this.state.data.filter((point) => point.Id.includes(this.state.query)).map((o, i) => {
            return (
              <tr>
                <td>{o.Id}</td>
                <td>{o.FirstName}</td>
              </tr>
            )
          })}

        </table>
      </div>
    )
  }
}


ReactDOM.render(<Filter/>, document.querySelector('#root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>