如何在状态挂钩中从获取请求中设置数据(对象数组)?

Posted

技术标签:

【中文标题】如何在状态挂钩中从获取请求中设置数据(对象数组)?【英文标题】:How to set data (array of objects) from get request in a state hook? 【发布时间】:2020-11-14 05:10:29 【问题描述】:

您好,我在我的 App 组件中使用 axios 获取数据,然后在我的 SearchResults 组件的屏幕上显示它。

我目前发出我的 get 请求(在用户输入输入字段后 - 在另一个组件中)并使用 setSearchResults 将所有数据存储在我的状态 searchResults 中。然后我将数据作为道具传递给我的 SearchResults 组件,并通过它使用 & 映射,并根据一些逻辑在屏幕上显示正确的数据。

我想知道直接在我的异步函数中而不是在 SearchResults 组件中的函数中执行我的逻辑是否更有效。

我试图在异步函数中执行逻辑(可以在下面找到),但我的结果没有正确显示。当我在输入字段中输入内容时,它会检索与用户输入内容无关的数据。保持原样会更好吗?它不起作用的原因是因为我在状态挂钩中错误地设置了我的 get 请求中的数据吗?任何帮助表示赞赏,在此先感谢您!

function App() 
    const [keyword, setKeyword] = useState("")
    const [searchResults, setSearchResults] = useState([])

    const getAllData = async () => 
        return await getDataService(keyword)
            .then(( data ) => 
                // currently I am just doing: 
                   setSearchResults(data.list)

                // my attempt below for doing the logic directly here 
                //instead of in showSearchResults() in my other component:
                return data.list.map((item) => 
                  if(item.searchterm.includes(keyword.toLowerCase())) 
                    setSearchResults([...searchResults, item])
                
              )
            )
            .catch((err) => console.log(err))
    

    return (
        <div className="App">
            <form className="container">
                <InputField keyword=keyword setKeyword=setKeyword getClothesData=getClothesData />
                <SearchResults keyword=keyword searchResults=searchResults />
            </form>
        </div>
    );


const SearchResults = ( keyword, searchResults ) => 
  const showSearchResults = () => 
    return searchResults.map((item, index) => 
      if (item.searchterm.includes(keyword.toLowerCase()) && keyword.length > 1) 
        return (
          <div className="text-bold" key=index>
            <ul>
              <li className="input-fields search-results">
               item.searchterm
              </li>
            </ul>
          </div>
        );
      
    );
  ;
  return <div> keyword ? showSearchResults() : null </div>;

【问题讨论】:

首先你应该分开获取数据和过滤数据。获取数据应该在 useEffect 挂钩中。此外,您还可以分阶段快速解决问题。 【参考方案1】:

看起来您尝试应用的逻辑不正确。

return data.list.map((item) => 
  if(item.searchterm.includes(keyword.toLowerCase())) 
    setSearchResults([...searchResults, item])

在这里,您正在映射列表中的项目,并一次又一次地设置searchResults 状态。 React 可能会使其成为批量更新,并且不会总是采用之前的状态值。

您可以通过在setSearchResults 中提供功能更新来避免这种情况发生

看看Why React useState with functional update form is needed?

【讨论】:

所以你的意思是把它设置为:setSearchResults(searchReslts =&gt; [...searchResults, item]) @critical_maas 是的!另外,我希望您关注此处共享的其他答案。例如,Tarakumi 分享的答案 我也关注了他的评论!谢谢。我尝试通过功能更新来提出建议,但我仍然得到不正确的结果。当我想要包含关键字的结果时,它会多次显示所有项目。【参考方案2】:

在 useEffect 挂钩中发出您的服务器请求: 模板是这样的:

const App = () => 
  const [state, setState] = useState([])
  
  useEffect(() => 
    axios(url).then(( data ) => setState(data))
  , []) // empty array here means that hooks works once


【讨论】:

谢谢!我对我的代码进行了此更改。欣赏它 很高兴听到它有帮助!如果您发现有用的答案,您可以投票给他们 - 这会提高声誉,也让我很高兴!

以上是关于如何在状态挂钩中从获取请求中设置数据(对象数组)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在本机反应中从平面列表中设置 Json 数组

如何在数组中设置特定对象的状态

React - 访问在 useEffect 挂钩中设置的对象属性

如何在反应中的对象数组中设置对象数组的状态

ReactJS中从父组件调用子函数时如何在子组件中设置状态

React - useEffect axios请求中设置的状态为空