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

React点击按钮路由跳转时触发Cannot update a component错误求助

React状态更新与路由跳转冲突的解决方案

问题原因

你遇到的Warning: Cannot update a component (Home) while rendering a different component (Posts)警告,本质是触发路由跳转后,立刻更新了Home父组件App的状态——此时Home组件已经进入卸载流程,而Posts正在渲染,React禁止在一个组件渲染期间去更新另一个组件的状态,所以抛出警告。

解决方案

方案1:调整执行顺序(快速修复)

把状态更新放到路由跳转之前,确保Home组件还未开始卸载时完成状态更新:

<button
  key={e.id + 10}
  onClick={() => {
    // 先更新状态,再跳转路由
    setResponse(e.id);
    navigate('/posts');
  }}
  className="btn"
>
  Posts
</button>

方案2:用URL参数传递数据(更规范的做法)

依赖父组件状态传递页面数据不符合路由设计的初衷,改用URL参数传递userId,彻底避免状态同步冲突:

  1. 修改Home组件的跳转逻辑:
<button
  key={e.id + 10}
  onClick={() => {
    // 将userId放入URL参数
    navigate(`/posts/${e.id}`);
  }}
  className="btn"
>
  Posts
</button>
  1. 更新App.js的路由配置:
function App() {
  // 不再需要这个共享状态
  // const [response, setResponse] = useState({});
  return (
    <Router>
      <Routes>
        <Route exact path="/" element={<Home />} />
        {/* 配置带参数的路由 */}
        <Route exact path="/posts/:userId" element={<Posts />} />
        <Route exact path="*" />
      </Routes>
    </Router>
  );
}
  1. 修改Posts组件获取参数:
import { useParams } from 'react-router-dom';

function Posts() {
  // 从URL参数中获取userId
  const { userId } = useParams();
  const dispatch = useDispatch();
  const navigate = useNavigate();
  const state = useSelector((state) => state);
  
  if (state.post.isLoading) {
    return <h1>Loading...</h1>;
  }
  if (!state.post.data) {
    dispatch(fetchPosts());
  }

  return (
    <div className="App">
      Posts
      {state.post.data &&
        state.post.data
          {/* 注意转换参数类型(URL参数是字符串) */}
          .filter((e) => e.userId === parseInt(userId))
          .map((e) => (
            <div key={`${e.userId}-${e.id}`}>
              <li key={e.id}>{e.title}</li>
            </div>
          ))}
      <button onClick={() => navigate('/')}>
        List of users
      </button>
    </div>
  );
}

补充说明

你之前尝试在onClick里直接用useEffect的写法是错误的——React Hook只能在组件顶层或自定义Hook中调用,不能在事件回调这类嵌套函数里使用,所以这种写法根本不会生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 23:50:14