React Router Link传递带方法的对象提示函数无法克隆错误
错误原因
你遇到的DataCloneError本质是浏览器History API的限制:React Router的Link组件传递state参数时,底层调用了History接口的pushState方法,该方法会通过结构化克隆算法对传入的state数据做序列化处理,而这个算法不支持克隆函数、Symbol、DOM节点等类型。你给Person对象挂载了getFullName方法,序列化时碰到函数就会抛出克隆失败的错误。
你后续的写法能正常运行,是因为你把getFullName从可执行函数改成了预计算的字符串属性,字符串属于结构化克隆算法支持的基础类型,因此可以正常传递。
推荐实现方案
方案1:纯数据传递+消费侧包装(最推荐)
Link组件的state仅传递从API获取的纯数据字段,不要挂载自定义方法。把姓名拼接等公共逻辑封装为通用工具函数,或者把Person类/构造函数抽成公共模块,在详情页拿到state数据后,再用公共模块把纯数据包装为带方法的实例即可。
代码示例:// 公共模块 Person.js export class Person { constructor(personData) { Object.assign(this, personData) } // 方法挂载在原型上,不需要参与序列化传递 getFullName() { return `${this.name.title} ${this.name.first} ${this.name.last}` } } // 主页Link组件传参 <Link to="/user/detail" state={ rawPersonData /* 直接传API返回的纯数据 */ }> 跳转详情 </Link> // 详情页消费数据 import { Person } from './Person.js' import { useLocation } from 'react-router-dom' function UserDetail() { const { state: rawPerson } = useLocation() const person = new Person(rawPerson) // 直接调用实例方法即可 return <p>{ person.getFullName() }</p> }这个方案的优势是方法复用性高,不会重复计算,也完全规避了序列化报错的问题。
方案2:预计算派生属性(适合数据不会动态变更的场景)
就是你当前在用的思路,在构造Person实例时直接把fullName计算为纯字符串属性,逻辑简单易维护,对于不需要动态修改用户信息的场景完全够用。
内容的提问来源于stack exchange,提问作者Zigoni
相关产品推荐
相关产品推荐

