You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在useEffect中使用setState更新数组状态的问题及渲染疑惑

问题描述

想要实现以下流程:

  1. 声明[reviewList, setReviewList] = useState<any>(null);
  2. 当reviewList === null时,JSX显示<div>Loading</div>;
  3. 当reviewList !== null时,JSX显示列表信息。

编写代码后运行看不到列表,推测是未触发重新渲染,需明确解决方案及对渲染逻辑的理解是否正确。

错误分析与解决方案

你对React状态更新触发重新渲染的理解是正确的,但代码存在几个具体错误导致列表无法显示:

1. map函数未返回元素

在条件渲染的map回调中,你用大括号{}包裹JSX但未显式返回元素,导致map返回的是全为undefined的数组,无法渲染出内容。

修正方式:

  • 给箭头函数添加return语句;
  • 或去掉大括号,利用箭头函数的隐式返回特性。

同时必须给每个map生成的元素添加唯一key属性,这是React列表渲染的要求,避免警告和性能问题。修正后的map代码:

reviewList.map((el : any)=> (
  <div className={styles.reviewEach} key={el.name}>
    <img className={styles.reviewEachImage} src={el.photo}/>
    <div className={styles.reivewTextBox}>
      <div className={styles.reviewNameAndRating}>
        <span>{el.name}</span>
        <img className={styles.reviewRatingStar} src="assets/star.png"/>
        <span className={styles.reviewEachRating} >{el.rating}</span>
      </div>
      <span className={styles.reviewEachInfo}>{el.info}</span>
    </div>
  </div>
))

2. 错误使用await包裹setReviewList

setReviewList是React useState返回的状态更新函数,不是异步函数,不需要用await包裹。且状态更新是异步批量执行的,在setReviewList后立刻console.log(reviewList),拿到的仍是更新前的旧值。

修正方式:
直接调用setReviewList即可;若要查看更新后的状态,可通过useEffect监听reviewList的变化。修正后的相关代码:

useEffect(()=>{
  console.log("初始渲染后的reviewList: ", reviewList);
  getListInfo();
  // 监听reviewList变化,查看更新后的值
  useEffect(()=>{
    console.log("reviewList更新后: ", reviewList);
  }, [reviewList])
},[])

let getListInfo = () => {
  console.log("更新前的reviewList: ", reviewList);
  setReviewList(list);
}

3. 状态更新后的渲染逻辑确认

调用setReviewList(list)后,React会标记组件需要重新渲染,再次执行组件函数时reviewList会变为list数组,此时条件渲染会进入map分支,只要map正确返回元素,就能正常显示列表。

完整核心代码示例
import { useState, useEffect } from 'react';
import styles from './YourComponent.module.css'; // 替换为你的样式文件路径

const YourComponent = () => {
  let [reviewList, setReviewList] = useState<any>(null);
  let list = [
    {
      photo : "assets/likelist1.png",
      name : "Island one",
      info : "300m · California",
      rating : "4.5(37)"
    },
    {
      photo : "assets/likelist2.png",
      name : "Island two",
      info : "300m · Maxico",
      rating : "4.3(300)"
    },
    {
      photo : "assets/likelist3.png",
      name : "Island three",
      info : "150m · Maxico",
      rating : "4.3(00)"
    },
    {
      photo : "assets/likelist1.png",
      name : "Island four",
      info : "300m · Dubai",
      rating : "4.5(11)"
    },
    {
      photo : "assets/likelist1.png",
      name : "Island five",
      info : "300m · Japan",
      rating : "3.9(01)"
    }
  ]

  useEffect(()=>{
    getListInfo();
  },[])

  let getListInfo = () => {
    setReviewList(list);
  }

  return (
    <div className={styles.reviewListBox}>
      {
        reviewList === null  
        ?
        <div>Loading</div>
        :
        reviewList.map((el : any)=> (
          <div className={styles.reviewEach} key={el.name}>
            <img className={styles.reviewEachImage} src={el.photo}/>
            <div className={styles.reivewTextBox}>
              <div className={styles.reviewNameAndRating}>
                <span>{el.name}</span>
                <img className={styles.reviewRatingStar} src="assets/star.png"/>
                <span className={styles.reviewEachRating} >{el.rating}</span>
              </div>
              <span className={styles.reviewEachInfo}>{el.info}</span>
            </div>
          </div>
        ))
      }
    </div>
  )
}

export default YourComponent;

内容的提问来源于stack exchange,提问作者Boris Park

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 22:45:35