1

我在 react 应用程序上有 2 个主要组件:一个是包含一堆数据的表格(使用Rsuite Table),另一个在表格上方,只是一个div带有多个input文本字段的表格。就这么简单:

输入字段

例如,如果在“firstName”输入字段中,用户只键入了一个T字母,则表格网格应立即仅显示名称中包含T的名称。这很好,我的实际问题是如何为您在上图中看到的 3 个输入实现这一点。也就是说,如果用户在多个输入文本框中输入内容?看看下面:

这是我的主要App.js外观:

function App() {
  const [dummyData, setDummyData] = useState([]);
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [city, setCity] = useState('');

  const firstNameHandler = (input) => {
    setFirstName(input);
  }
  const lasttNameHandler = (input) => {
    setLastName(input);
  }
  const firstNameHandler = (input) => {
    setCity(input);
  }

  useEffect(() => {
    const generateRandomData = () => {
      setDummyData([...Array(100).keys().map(key => {
        return {
          firstName: faker.name.firstName(),
          lastName: faker.name.lastName(),
          city: faker.address.city()
        }
      })
    )}  
    generateRandomData();
  }, []);

  return(
    <Filters changeFirstName={firstNameHandler} changeLastName={lastNameHandler} changeCity={cityHandler}/>
    <InfoTable items={dummyData}/>
);
  
}
export default App;

PS:状态正在从Filters组件中提升。我用来useEffect在组件首次加载时生成随机数据。传入的dummyDataInfoTable只是一个数组,其中包含使用faker.js随机生成的对象,它们看起来像这样:

{
 firstName: "John",
 lastName: "Smith",
 city: "San Francisco"
}

我的Filters.js组件如下所示:

function Filters = (props) => {
  const firstNameInputHandler = (event) => {
    props.changeFirstName(event.target.value);
  }
  const lastNameInputHandler = (event) => {
    props.changeLastName(event.target.value);
  }
  const cityInputHandler = (event) => {
    props.changeCity(event.target.value);
  }
  
  return(
    <div className="user_inputs">
      <label htmlFor="firstName">First Name:</label>
      <input id="firstName" type="text" onChange={firstNameInputHandler}/>
    </div>
    <div className="user_inputs">
      <label htmlFor="lastName">Last Name:</label>
      <input id="lastName" type="text" onChange={lastNameInputHandler}/>
    </div>
    <div className="user_inputs">
      <label htmlFor="city">City:</label>
      <input id="city" type="text" onChange={cityInputHandler}/>
    </div>
  );
}
export default Filters;

所以在这里你可以看到,我正在提升状态,所以我让它们可用,App.js这样我就可以过滤我传递给 table props 的数组。

我的InfoTable.js组件非常直截了当,再次使用Rsuite Table看起来像这样:

function InfoTable = (props) => {
  return(
    <Table virtualized height={500} data={props.items} rowHeight={30}>
       <Column width={60}>
         <HeaderCell>First Name</HeaderCell>
         <Cell dataKey="firstName"/>
       </Column>
       <Column width={60}>
         <HeaderCell>Last Name</HeaderCell>
         <Cell dataKey="lastName"/>
       </Column>
       <Column width={60}>
         <HeaderCell>City</HeaderCell>
         <Cell dataKey="city"/>
       </Column>
    </Table>
  );
}
export default InfoTable;

该表显示确实很好,但我想要的是根据用户可能输入或不输入的各种文本字段过滤的数据。例如:如果用户在名字输入字段中键入Jo,在姓氏输入字段中键入S,我希望表格仅显示符合此条件的对象。然后,如果用户键入California,我希望该表重新调整为仅来自加利福尼亚州的人,其名字包含Jo和姓氏包含S。如果用户删除所有内容,该表应该是原始的 100 个值。

我认为问题的一小部分的一种方法是,在App.js我检查 firstName 状态长度是否大于 0 时,如果是,我在.filter作为道具传递的数组上运行。因此,在返回内部,关于网格组件,我有条件地将其渲染为烂:

return(
  bla bla bla (...)
  {firstName.length === 0 && <InfoTable items={dummyData} />
  {firstName.length > 0 && <InfoTable items={dummyData.filter((obj) => {
    return obj.firstName.includes(firstName)})
  }
);

我可以“有点”使用这种方法来检查字段中是否有输入,并使用 100 行呈现表格或按该标准过滤。问题是,我如何使这对 3 个输入起作用?例如:如果用户在First Name输入字段中键入Jo ,在Last Name输入字段中键入S,我希望表仅显示符合此条件的行(名字包含Jo和姓包含S的对象) . 然后,如果用户在City字段中键入 California ,我希望该表重新调整为仅来自加利福尼亚的人,其名字包含Jo,姓氏包含S. 如果用户从所有 3 个输入中删除文本,表格应该重新调整以显示原始的 100 个值。

请帮忙。

4

2 回答 2

0

对不起,我没有足够的声誉来发表评论,所以我回答了这个问题

如果这是一个演示,或者数据量很小,我认为filter完全可以,只需简单地链接过滤器:

const newData = originalData.filter(condition1).filter(condition2).filter(condition3)

如果这是一个高效的 Web 应用程序,也许我们应该让后端的 API 来处理过滤器,因为数据可能很大并且可能依赖于某种搜索引擎

如果你真的只想在客户端做,而且数据可能也很大,应该有一些技术,比如只针对客户端的搜索引擎,但我没有这部分的经验

于 2021-06-13T15:41:38.967 回答
0

考虑到给出的示例,解决方案非常简洁:

const filterCriteria = (obj) => {
  return obj.firstName.includes(firstName)
  && obj.lastName.includes(lastName)
  && obj.city.includes(city);
}

return(
  <InfoTable items={dummyData.filter(filterCriteria)} />
);

这提供了所需的结果。

于 2021-06-25T14:03:50.417 回答