【问题标题】:Make table with filter in react failed在反应中使用过滤器制作表格失败
【发布时间】:2017-12-15 12:46:45
【问题描述】:

我能够使过滤器工作,但只需使用 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

【问题讨论】:

  • 一个选项是,将相同的数据存储两次,(originalData,filteredData)两者的初始值将相同,并且始终从 originalData 中过滤数据并在过滤数据中更新。
  • @MayankShukla 是的,我想我明白了!
  • 样例:codesandbox.io/s/ko5yk719r,这就是你想要的?

标签: javascript reactjs ecmascript-6


【解决方案1】:

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

【讨论】:

  • @JennyMok 你能解释一下吗?
【解决方案2】:

首先:您将要使用includes() 进行过滤以提高可用性。否则,除非它们 100% 相同,否则它们将不匹配。一旦您开始处理超过一位数的字段,这将很重要。

其次:通过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>

【讨论】:

  • 您可以在filter() 中添加或声明|| 以检查其他匹配项
  • 如果您决定添加更多字段
【解决方案3】:

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

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

它可能看起来像这样:

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。开头的大写字母只能在声明类时使用。

【讨论】:

  • 请在发布无效的非工作代码之前测试您的答案。
  • 抱歉,我的组件中有样式变量,但忘记在此处复制。我删除了样式,现在它就像一个魅力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-27
  • 1970-01-01
  • 1970-01-01
  • 2021-04-10
  • 2018-08-03
相关资源
最近更新 更多