【问题标题】:React mapping through a query result is not working通过查询结果进行反应映射不起作用
【发布时间】:2020-10-23 17:36:37
【问题描述】:

我正在使用 React,我正在尝试将 GET 请求的结果映射到数据库以在我的页面中显示一些选项卡。

这是我的 GET 请求:

useEffect(async ()=>{
  const a = await getCategories();
  setCategories(a)
    
},[])
  
const [categories, setCategories] = useState()

然后我使用 useEffect 挂钩将返回的数组存储在我的功能组件状态中:

useEffect(async ()=>{
  const a = await getCategories();
  setCategories(a)

},[])
  
const [categories, setCategories] = useState()

最后,在渲染中,我尝试像这样映射状态数组:

<Nav variant="tabs" >
  {categories.map((category, index) => (
    <Nav.Item key={index}>
      <Nav.Link
      eventKey={`link-${index}`}
      onClick={() => setCategory(category.category)}
      >
        {category}
      </Nav.Link>
    </Nav.Item>
  ))}
</Nav>

我收到 TypeError: Cannot read property 'map' of undefined

我认为这是因为它在我将数组存储在状态之前运行地图,但我不知道如何解决它。

【问题讨论】:

  • 你能提供getCategories()的代码吗?
  • @yuRa 代码运行良好,我用邮递员对其进行了测试,并按预期返回了一个数组

标签: javascript reactjs async-await react-hooks


【解决方案1】:

您可以使用空数组设置类别的默认值:

const [categories, setCategories] = useState([])

您还可以选择通过检查类别是否可迭代来添加防御性条件映射:

{Array.isArray(categories) && categories.map((category, index) => (..)}

【讨论】:

  • 这如何回答这个问题?
  • 它怎么不回答这个问题:D?
  • 非常感谢!因此,通过将空数组映射到空数组,当我分配从数据库中获取的数组时,它再次映射到新数组,对吗?
【解决方案2】:

useEffect 中的async 会引起警告,所以像这样使用它:Ref

useEffect(()=>{

const fetchData = async () => {
      const a = await getCategories();
      setCategories(a);
    };
 
    fetchData();

},[])

并在状态中声明一个默认的空数组:

const [categories, setCategories] = useState([]);

或者您可以像这样验证类别是否可用于迭代:

<Nav variant="tabs" >
  {categories.length > 0 && categories.map((category, index) => (
    <Nav.Item key={index}>
      <Nav.Link
      eventKey={`link-${index}`}
      onClick={() => setCategory(category.category)}
      >
        {category}
      </Nav.Link>
    </Nav.Item>
  ))}
</Nav>

【讨论】:

  • 很好,现在可以使用了,谢谢!为什么 useEffect 上的 async await 会导致问题,但 useEffect 内部的 async await 不会?让我有点困惑。
  • 你可以在这里阅读。 robinwieruch.de/react-hooks-fetch-data
【解决方案3】:

是的,你是对的,在渲染之前,类别是空的。您必须在渲染之前检查类别是否为空:

return !categories.length ?   
 <Nav variant="tabs" >
   {categories.map((category, index) => (
     <Nav.Item key={index}>
       <Nav.Link
         eventKey={`link-${index}`}
         onClick={() => 
 setCategory(category.category)}
      >
        {category}
      </Nav.Link>
    </Nav.Item>
  ))}
</Nav>

:
<h1>Loading...</h1>

【讨论】:

    【解决方案4】:

    不看setCategories()很难回答

    您可以通过在映射之前检查数组是否存在来解决此问题

    array & array.map(item => {
        return item * 2
    })
    

    这不会返回 undefined 因为第一个条件会失败。

    【讨论】:

    • setCategories 是 useState 钩子的一部分。它作为基于类的组件的 this.setState 工作。
    猜你喜欢
    • 2021-11-21
    • 1970-01-01
    • 2012-08-05
    • 2018-12-30
    • 1970-01-01
    • 2014-12-29
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    相关资源
    最近更新 更多