React中克隆传入组件的props数据遇只读属性赋值错误求助
问题分析与解决方法
错误根源
你遇到的Cannot assign to read only property 'selectedData' of object错误,核心原因是React的props是只读的,绝对不能直接修改props的属性值(比如props.selectedData = data这种操作)。此外你的数据流逻辑也有问题:父组件的clonedData是普通变量,无法追踪更新,子组件的修改也无法同步回父组件。
分步解决方案
1. 修改父组件(App.js):将普通变量改为React状态
把父组件中的clonedData改成React状态,同时添加回调函数接收子组件的选中数据,实现双向数据同步:
import React, { useState } from 'react'; import MultiDropdown from './Components/MultiDropdown/MultiDropdown.component'; import { allOptions } from './Utils/DummyData'; import "./App.css"; const App = () => { // 将普通变量转为React状态,用于追踪更新 const [clonedData, setClonedData] = useState([ { value: 'Normal😐', label: 'Normal😐' }, { value: 'Angry😡', label: 'Angry😡' }, { value: 'Love😍', label: 'Love😍' }, ]); // 定义回调,接收子组件传来的选中值并更新父状态 const handleSelectedUpdate = (selectedValues) => { // 把选中的value映射为和初始结构一致的对象数组 const updatedData = selectedValues.map(value => ({ value, label: value })); setClonedData(updatedData); }; return( <div className='app'> <MultiDropdown data={allOptions} placeholder="Select Options" selectedData={clonedData} onSelectedUpdate={handleSelectedUpdate} {/* 传递回调给子组件 */} /> <button onClick={() => console.log("Selected", clonedData)}>Click to See SelectedData</button> </div> ) } export default App;
2. 修改子组件(MultiDropdown.tsx):移除props修改逻辑,通过回调同步数据
去掉直接修改props的代码,改用父组件传递的回调函数同步选中状态,同时监听父组件的selectedData变化以同步子组件内部状态:
import React, { useEffect, useState } from 'react'; // 明确Props类型,包含回调函数 type Props = { data: any[]; placeholder: string; selectedData: { value: string; label: string }[]; onSelectedUpdate: (selectedValues: string[]) => void; }; export default function MultiDropdown(props: Props): React.ReactNode { // 从父组件props初始化子组件内部状态 const [selectedValues, setSelectedValues] = useState( props.selectedData.map(opt => opt.value) ); // 监听父组件selectedData变化,同步子组件状态 useEffect(() => { setSelectedValues(props.selectedData.map(opt => opt.value)); }, [props.selectedData]); // 处理下拉框选择变化,同时调用父组件回调同步数据 const handleDropdownChange = (selected: any[]) => { const values = selected.map(opt => opt.value); setSelectedValues(values); // 把选中值传给父组件更新状态 props.onSelectedUpdate(values); }; return ( <div> <Select {...DropDownProps(props, selectedValues, SelectOption)} onChange={handleDropdownChange} /> {selectedValues.map(opt => ( <ListContainer key={opt} opt={opt} data={selectedValues} set={setSelectedValues} /> ))} </div> ); }
关键修改点说明
- 移除了子组件中
props.selectedData = data的错误代码,严格遵循React props只读原则 - 父组件通过
useState管理选中数据,确保状态变化能触发组件重渲染 - 子组件通过回调函数
onSelectedUpdate将选中数据传递回父组件,实现双向数据同步 - 去掉了子组件中错误的
ref={props.selectedData}配置(ref不能绑定普通数组)
内容的提问来源于stack exchange,提问作者Rokkie
相关产品推荐
相关产品推荐

