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

React中如何为数组内被点击的项单独设置loading状态

问题根因

你当前的loading是全局布尔状态,所有列表项共享这一个状态值,所以只要触发一次加载,所有项都会匹配到state.loading === true的判断,同步显示加载状态。

解决方案

调整状态结构,不再用布尔值记录加载状态,改为存储当前正在加载的列表项的唯一标识,比如这里可以直接用车名(业务上对唯一性要求高的话也可以用专门的id字段),渲染时只给标识匹配的项显示加载状态即可。

调整后的代码示例

// 首先调整reducer的初始状态,把loading的初始值从false改成null
const initialState = {
  // 其他原有状态
  loading: null // 存储当前加载项的唯一标识,未加载时为null
}

// reducer里的SET_LOADING逻辑对应调整:
function reducer(state, action) {
  switch(action.type) {
    case "SET_LOADING":
      return { ...state, loading: action.payload }
    // 其他原有case
    default: return state
  }
}

export default function App() {
  const [state, dispatch] = useReducer(reducer, initialState);
  const cars = [{ name: "Benz" }, { name: "Jeep" }, { name: "BMW" }];

  // 点击时接收当前点击项的name作为参数
  const handleClick = async (carName) => {
    // 把当前点击项的name设置到loading状态
    dispatch({ type: "SET_LOADING", payload: carName });
    try {
      // 这里放你的API调用逻辑
      // await yourApiRequest()
    } finally {
      // 请求结束(无论成功失败)都把loading重置为null
      dispatch({ type: "SET_LOADING", payload: null });
    }
  };
  return (
    <div className="App">
      {cars.map(({ name }) => (
        <button key={name} onClick={() => handleClick(name)}>
          {/* 只有当前项的name和存储的loading标识相等时才显示加载 */}
          {state.loading === name ? "Loading..." : name}
        </button>
      ))}
    </div>
  );
}
可选优化

如果你的业务存在多个项同时加载的场景,可以把loading改成Set结构,存储所有正在加载的项的标识,判断的时候用state.loading.has(name)即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 01:21:03