首页 > 解决方案 > 用过滤器反应 JS 表

问题描述

我正在尝试调整在此处的 react js 文档中找到的此表, 遇到了一些奇怪的问题,如下面的屏幕截图所示。 在此处输入图像描述

我们尝试过滤 lBir

在此处输入图像描述

最终结果是我得到了额外的行。这是所有荣耀的代码。

import React from 'react';
import ReactDOM from 'react-dom';
  
  class UserRow extends React.Component {
    render() {
      const user = this.props.user;
      const name = user.name;
  
      return (
        <tr>
          <td>{name}</td>
          <td>{user.system}</td>
        </tr>
      );
    }
  }
  
  class UserTable extends React.Component {
    render() {
      const filterText = this.props.filterText;  
      const rows = [];  
      this.props.users.forEach((user) => {
        console.log(this.props.users);
        if (user.name.indexOf(filterText) === -1) {
        //   console.log('filter text = -1')
          return;
        }
        rows.push(
          <UserRow
            user={user}
            key={user.name}
          />
        );
      });
  
      return (
        <table>
          <thead>
            <tr>
              <th>Name</th>
              <th>system</th>
            </tr>
          </thead>
          <tbody>{rows}</tbody>
        </table>
      );
    }
  }
  
  class SearchBar extends React.Component {
    constructor(props) {
      super(props);
      this.handleFilterTextChange = this.handleFilterTextChange.bind(this);
    }
    
    handleFilterTextChange(e) {
      this.props.onFilterTextChange(e.target.value);
    }
    
    render() {
      return (
        <form>
          <input
            type="text"
            placeholder="Search..."
            value={this.props.filterText}
            onChange={this.handleFilterTextChange}
          />
        </form>
      );
    }
  }
  
  class FilterableUserTable extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        filterText: ''      
    };
      
      this.handleFilterTextChange = this.handleFilterTextChange.bind(this);
    }
  
    handleFilterTextChange(filterText) {
        console.log(filterText);
      this.setState({
        filterText: filterText
      });
    }
    
    render() {
      return (
        <div>
          <SearchBar
            filterText={this.state.filterText}
            onFilterTextChange={this.handleFilterTextChange}
          />
          <UserTable
            users={this.props.users}
            filterText={this.state.filterText}
          />
        </div>
      );
    }
  }
  
  
  const USERS = [
    {name: 'lJames', system: 'test@testy.com'},
    {name: 'lJames', system: 'test@tester.com'},
    {name: 'lBird', system: 'lbird@moretesting.com'},
    {name: 'mJordan', system: 'lbird@somemore.com'},
    {name: 'tester', system: 'mjordan@nba.com'},
  ];
  
  ReactDOM.render(
    <FilterableUserTable users={USERS} />,
    document.getElementById('container')
  );
  
  
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="theme-color" content="#000000" />
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="container"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

我可以在控制台中看到以下警告:“警告:遇到两个具有相同密钥的孩子,lJames. 密钥应该是唯一的,以便组件在更新时保持其身份。非唯一密钥可能会导致孩子被复制和/或省略 -该行为不受支持,可能会在未来版本中更改。”

任何帮助将不胜感激!

标签: javascriptreactjs

解决方案


React 使用键作为识别列表中组件的一种方式,并且它们在该列表中应该是唯一的(React 文档)。如果有多个组件具有相同的键,则可能会导致您所看到的问题(因为您将name其用作键,并且两个用户具有 name lJames)。

您可以通过给每个用户一个唯一的id属性来解决这个问题,或者使用连接的用户和电子邮件作为键 -key={user.name + user.system}


推荐阅读