根据用户输入渲染元素列表

Render list of elements based on user's input

上下文 我是 React 的新手,所以我正在构建基本表单,我想在其中根据用户的输入显示国家列表。我的应用程序由两个组件组成:过滤器(这是用户输入的输入字段)和显示(这将显示满足用户输入的国家/地区

到目前为止,我已经能够将用户的输入记录到控制台。但是,在 useEffect() 挂钩中,当我添加一行以将国家/地区状态数组更新为用户输入时,没有任何反应。如何使用用户的输入更新国家/地区数组?

代码 App.js

import React, {useEffect, useState} from 'react'
import axios from 'axios'
import Filter from './components/Filter'
import Display from './components/Display'


function App() {
  const [countries, setCountries] = useState(['france', 'spain', 'germany', 'greece', 'portugal'])
  const [searchTerms, setSearchTerms] = useState('')
  const handleSearchInput = (event) => setSearchTerms(event.target.value)


  useEffect(() => {
   let results = countries.filter(country => country === searchTerms)
      console.log("results: ", results)
      setSearchTerms(searchTerms)
      setCountries(results)
  }, [])


  return (
    <div>
      <h1>Countries</h1>
      <Filter value={searchTerms} handleChange={handleSearchInput}/>
      <Display filteredArr={countries}/>
    </div>
  );
}

export default App;

显示

import React from 'react'

export default function Display({filteredArr, arr}){ 
    return(
        <p>
            {filteredArr.map(country => <div>{country}</div>)}
        </p>
    )
}

过滤器组件

export default function Filter({searchResult, handleChange}){
    return(
        <div>
            <input value={searchResult} onChange={handleChange} placeholder='Search for countries'/>
        </div>
    )
}

由于 effect hook 有一个空的依赖数组,它只在挂载上运行 - 在挂载上,searchTerms 字符串是空的,所以 results 数组也将是空的。

不要使用效果挂钩 - 而是使用 handleSearchInput 过滤器和设置状态。您还需要一个持久的国家/地区列表 - 如果您过滤并设置国家/地区的状态,并且用户输入再次更改,您将需要随后过滤 original 列表国家,而不是 already-filtered 国家列表。

function App() {
  const initialCountries = ['france', 'spain', 'germany', 'greece', 'portugal'];
  const [countries, setCountries] = React.useState(initialCountries)
  const [searchTerms, setSearchTerms] = React.useState('')
  const handleSearchInput = (event) => {
    setSearchTerms(event.target.value);
    setCountries(
      initialCountries.filter(
        country => country === event.target.value
      )
    );
  };
  return (
    <div>
      <h1>Countries</h1>
      <Filter value={searchTerms} handleChange={handleSearchInput}/>
      <Display filteredArr={countries}/>
    </div>
  );
}

function Display({filteredArr, arr}){ 
    return(
        <p>
            {filteredArr.map(country => <div>{country}</div>)}
        </p>
    )
}
function Filter({searchResult, handleChange}){
    return(
        <div>
            <input value={searchResult} onChange={handleChange} placeholder='Search for countries'/>
        </div>
    )
}

ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>

不过您当前的逻辑似乎有点奇怪 - 您真的只想显示与输入完全匹配的国家吗?我不确定您要在这里实现什么,但如果您只想要完全匹配,则可能 user-friendly 使国家/地区可点击以切换它们,而不是使用文本输入。如果要显示包含相同用户输入子字符串的多个国家/地区,请在过滤器测试中使用 .includes 而不是 ===

如果输入为空,您可能还想再次显示所有国家/地区,在这种情况下您会这样做:

setCountries(
  event.target.value === '' ? initialCountries : initialCountries.filter(
    country => country === event.target.value
  )
);

在 useEffect Hook 依赖值中,当依赖值发生变化时调用 useEffect 钩子。 使用效果(()=> { .....你的代码 }, [依赖项])

 const [countries, setCountries] = useState(['france', 'spain', 
'germany', 
 'greece', 'portugal'])
  const [searchTerms, setSearchTerms] = useState('')
  const handleSearchInput = (event) =>{
  setSearchTerms(event.target.value)
  let results = countries.filter(country => country === 
 event.target.value)
  setCountries(results)
  } 


  useEffect(() => {
   let results = countries.filter(country => country === searchTerms)
   console.log("results: ", results)
   setSearchTerms(searchTerms)
   setCountries(results)
  }, [])

或者只有你可以使用这个

   const [countries, setCountries] = useState(['france', 'spain', 
 'germany', 
 'greece', 'portugal'])
  const [searchTerms, setSearchTerms] = useState('')
  const handleSearchInput = (event) =>{
  setSearchTerms(event.target.value)
  } 

  useEffect(() => {
   let results = countries.filter(country => country === searchTerms)
   console.log("results: ", results)
   setSearchTerms(searchTerms)
   setCountries(results)
  }, [searchTerms])