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

React卡片点击切换样式后跳转路由选中状态丢失问题咨询

问题根源

你当前的选中状态(勾选状态、背景色、边框样式)都存储在Card组件的内部useState中,路由跳转后组件会重新挂载/渲染,内部状态会重置为初始值,因此选中状态丢失。

解决方案

这里提供两种适配不同场景的实现方案:

方案1:和路由参数绑定(最适配你当前的场景)

你跳转后的路由本身就携带了选中卡片的id,直接从路由读取当前选中id和当前卡片id做对比,就能自动判断激活状态,不需要额外维护状态:

import React from "react";
import { useHistory, useParams } from "react-router";
import styled from "styled-components";

export default function Card(props) {
  const {item,id} = props;
  const history = useHistory();
  // 直接从动态路由参数取当前激活的id,路由配置为/invoice/:id时可用
  const { id: activeId } = useParams();
  // 直接判断当前卡片是否激活
  const isChecked = activeId === id;
  // 通过激活状态直接计算样式,不需要单独存state
  const background = isChecked ? "#fff" : "#F3F1FA";
  const cardBorder = isChecked ? "2px solid #7f67ce" : "transparent";

  const handleCheck = () => {
    history.push(`/invoice/${id}`) 
  };
  
  return (
    <CardWrapper
      onClick={handleCheck}
      background={background}
      cardBorder={cardBorder}
    >
     <div> Content </div>
      <Check>
        <input
          type="checkbox"
          checked={isChecked}
          onChange={handleCheck}
        />
      </Check>
    </CardWrapper>
  );
}

// 样式部分保持原有逻辑即可
const CardWrapper = styled.button`
  background-color: ${(props) => props.background};
  border: ${(props) => props.cardBorder};
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 347px;
  height: 129px;
  border-radius: 16px;
  color: #7f67ce;
  padding-left: 25px;
  padding-right: 25px;
  text-align: left;
  margin-top:10px;
  margin-bottom:10px;
  img {
    padding-bottom: 15px;
  }
  @media(max-width:1200px){
    width:300px;
  }
  @media(max-width:1200px){
    width:280px;
  }
  :first-child{
    margin-top:0px;
  }
`;

这个方案的优势是完全不需要额外维护状态,刷新页面后选中状态也不会丢失,和路由完全同步。

方案2:状态提升到父组件

如果你需要支持多选、或者不需要和路由绑定的场景,可以把选中状态提到渲染卡片列表的父组件中存储:

  • 父组件维护一个activeId(多选场景可以用activeIdList)状态
  • 把activeId和修改状态的方法通过props传给每个Card组件
  • 卡片内部不用存状态,直接通过props传入的activeId判断是否激活,点击时调用父组件的修改方法更新状态,再跳转路由
    这种方式状态存在父组件,只要父组件不卸载,跳转路由回来状态也不会丢失。

原有代码的其他优化点

  • 原有input的onChange={() => CheckBox}没有执行函数,点击复选框本身不会触发状态变更,修复为onChange={handleCheck}即可
  • 样式不需要单独存state,可以直接通过激活状态计算得出,减少冗余状态
  • 函数名CheckBox容易和UI组件混淆,建议改为语义化的事件处理函数名比如handleCheck

内容的提问来源于stack exchange,提问作者D.B.J

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:09:04