繁体   English   中英

未捕获的类型错误:无法分配给 object 的只读属性'#<object> '<div id="text_translate"><p> 对于我目前正在处理的代码,我有一个非常复杂的数组,里面装满了对象。 本页的重点是一次更改数组中一个 object 的一个属性,因此,需要更新整个数组以执行该更改。 该数组被初始化为...</p><pre> const [allDevices, setAllDevices] = useState(initialDeviceNames)</pre><p> 其中 intialDeviceNames 要么是从查询中获取的填充 object,要么是空数组(如果没有匹配的实例)。 看起来像这样...</p><p> <strong>请注意,空的 object(如果没有找到具有匹配日期值的值)会将每个数字属性设置为{id: null, name: "No Driver Selected"}</strong></p><pre> 0: 0: {id: 'dfebc7ce-ea4b-48d4-9fd9-7c2d02572e40', name: 'DANIEL STITT', type: 'Vehicle'} 1: {id: '64303dc1-0ba6-43bb-a25a-9885f9e8f2e3', name: 'KE.NETH WILLIFORD', type: 'Vehicle'} 2: {id: '1a778957-b679-401b-972d-aeb32f84e667', name: 'JASON PITSNOGLE', type: 'Vehicle'} 3: {id: '1fcc9d60-fc6f-4e34-b5ab-c64d5ea8778a', name: 'VIRGINIA SHADE', type: 'Vehicle'} 4: {id: null, name: 'No Driver Assigned'} 5: {id: null, name: 'No Driver Assigned'} 6: {id: null, name: 'No Driver Assigned'} amount: 6 name: "Vehicle" remaining_drivers: (60) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] [[Prototype]]: Object 1: 0: {id: '1a778957-b679-401b-972d-aeb32f84e667', name: 'JASON PITSNOGLE', type: 'iPad'} 1: {id: 'dfebc7ce-ea4b-48d4-9fd9-7c2d02572e40', name: 'DANIEL STITT', type: 'iPad'} 2: {id: '1fcc9d60-fc6f-4e34-b5ab-c64d5ea8778a', name: 'VIRGINIA SHADE', type: 'iPad'} 3: {id: '203726da-dba7-4f74-9d86-919d6a02a282', name: 'DONNA HAGGERTY', type: 'iPad'} 4: {id: null, name: 'No Driver Assigned'} 5: {id: null, name: 'No Driver Assigned'} 6: {id: null, name: 'No Driver Assigned'} 7: {id: null, name: 'No Driver Assigned'} 8: {id: null, name: 'No Driver Assigned'} 9: {id: null, name: 'No Driver Assigned'} 10: {id: null, name: 'No Driver Assigned'} amount: 10 name: "iPad" remaining_drivers: (60) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] [[Prototype]]: Object</pre><p> 所以一次更新这个显然很复杂。 我必须在数组中找到正确的 object,然后在该 object 中找到正确的数字属性,更改它,然后获取整个 state 进行更新。 在我添加一些预填充功能之前,我为此使用的代码一直有效。 更新这些单个属性中的任何一个的代码将在下面显示...</p><pre> const handleDriverSelection = (driver, index, superIndex, deviceObj) => { // If driver is the same if (allDevices[superIndex][index].name == `${driver.firstname} ${driver.lastname}`){ } // If active driver is empty else if (allDevices[superIndex][index].name == "No Driver Assigned" || allDevices[superIndex][index] == 'undefined'){ console.log(allDevices) let newArray = [...allDevices] // The specific device drop selected will be set equal the the driver clicked newArray[superIndex][index] = { name: `${driver.firstname} ${driver.lastname}`, id: driver.id, type: deviceObj.name } // This removes the driver from the list of remaining driver newArray[superIndex].remaining_drivers = newArray[superIndex].remaining_drivers.filter( (remDriver) => { if (driver.= remDriver){ return remDriver } }) // This sets the state setAllDevices(newArray) } // if active driver exists but is NOT the one inputted else if (allDevices[superIndex][index].name.= "No Driver Assigned" ){ console.log(allDevices) let newArray = [...allDevices] // This finds the driver that was previously selected and adds him/her back to the remaining list // For each driver... user.drivers.forEach( (dspDriver) => { // if the driver iterated == the driver that was previously selected if (allDevices[superIndex][index].name == `${dspDriver.firstname} ${dspDriver.lastname}`){ // Adds the driver to remaining drivers newArray[superIndex].remaining_drivers = [..,newArray[superIndex]:remaining_drivers. dspDriver] // Sets the current drop state to the driver selected newArray[superIndex][index] = { name. `${driver,firstname} ${driver:lastname}`. id, driver:id. type. deviceObj.name } // Removes the driver selected from the list of remaining drivers newArray[superIndex].remaining_drivers = newArray[superIndex],remaining_drivers.filter( (remDriver, index) => { if (driver != remDriver){ return remDriver } }) setAllDevices(newArray) } }) } }</pre><p> 这是我感到非常困惑的地方——通过这条线</p><pre>let newArray = [...allDevices]</pre><p> 我认为 newArray 创建的数组与allDevices的内容完全相同。 allDevices ,因为它是本地 state,所以是只读的。 我明白这一点。 我也明白,如果我写了let newArray = allDevices ,那么newArray也将是只读的,因为它不是一个新数组,而只是一个指向allDevices值的不同变量。 因此,我不知道为什么这个 ISNT 有效,因为newArray根本不应该是只读的。 我添加的代码有大量复杂的 useEffects 来处理查询、修改和刷新,所以我看不出它会如何影响我上面显示的代码,特别是因为newArray除了这段代码外不存在。</p></div></object>

[英]Uncaught TypeError: Cannot assign to read only property of object '#<Object>'

对于我目前正在处理的代码,我有一个非常复杂的数组,里面装满了对象。 本页的重点是一次更改数组中一个 object 的一个属性,因此,需要更新整个数组以执行该更改。 该数组被初始化为...

const [allDevices, setAllDevices] = useState(initialDeviceNames)

其中 intialDeviceNames 要么是从查询中获取的填充 object,要么是空数组(如果没有匹配的实例)。 看起来像这样...

请注意,空的 object(如果没有找到具有匹配日期值的值)会将每个数字属性设置为{id: null, name: "No Driver Selected"}

0:
0: {id: 'dfebc7ce-ea4b-48d4-9fd9-7c2d02572e40', name: 'DANIEL STITT', type: 'Vehicle'}
1: {id: '64303dc1-0ba6-43bb-a25a-9885f9e8f2e3', name: 'KENNETH WILLIFORD', type: 'Vehicle'}
2: {id: '1a778957-b679-401b-972d-aeb32f84e667', name: 'JASON PITSNOGLE', type: 'Vehicle'}
3: {id: '1fcc9d60-fc6f-4e34-b5ab-c64d5ea8778a', name: 'VIRGINIA SHADE', type: 'Vehicle'}
4: {id: null, name: 'No Driver Assigned'}
5: {id: null, name: 'No Driver Assigned'}
6: {id: null, name: 'No Driver Assigned'}
amount: 6
name: "Vehicle"
remaining_drivers: (60) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
[[Prototype]]: Object
1:
0: {id: '1a778957-b679-401b-972d-aeb32f84e667', name: 'JASON PITSNOGLE', type: 'iPad'}
1: {id: 'dfebc7ce-ea4b-48d4-9fd9-7c2d02572e40', name: 'DANIEL STITT', type: 'iPad'}
2: {id: '1fcc9d60-fc6f-4e34-b5ab-c64d5ea8778a', name: 'VIRGINIA SHADE', type: 'iPad'}
3: {id: '203726da-dba7-4f74-9d86-919d6a02a282', name: 'DONNA HAGGERTY', type: 'iPad'}
4: {id: null, name: 'No Driver Assigned'}
5: {id: null, name: 'No Driver Assigned'}
6: {id: null, name: 'No Driver Assigned'}
7: {id: null, name: 'No Driver Assigned'}
8: {id: null, name: 'No Driver Assigned'}
9: {id: null, name: 'No Driver Assigned'}
10: {id: null, name: 'No Driver Assigned'}
amount: 10
name: "iPad"
remaining_drivers: (60) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
[[Prototype]]: Object

所以一次更新这个显然很复杂。 我必须在数组中找到正确的 object,然后在该 object 中找到正确的数字属性,更改它,然后获取整个 state 进行更新。 在我添加一些预填充功能之前,我为此使用的代码一直有效。 更新这些单个属性中的任何一个的代码将在下面显示...

const handleDriverSelection = (driver, index, superIndex, deviceObj) => {
        // If driver is the same 
        if (allDevices[superIndex][index].name == `${driver.firstname} ${driver.lastname}`){
        }

        // If active driver is empty
        else if (allDevices[superIndex][index].name == "No Driver Assigned" || allDevices[superIndex][index] == 'undefined'){
            console.log(allDevices)
            let newArray = [...allDevices]

            // The specific device drop selected will be set equal the the driver clicked
            newArray[superIndex][index] = {
                name: `${driver.firstname} ${driver.lastname}`, 
                id: driver.id,
                type: deviceObj.name
            }

            // This removes the driver from the list of remaining driver
            newArray[superIndex].remaining_drivers = newArray[superIndex].remaining_drivers.filter( (remDriver) => {
                if (driver != remDriver){
                    return remDriver
                }
            })


            // This sets the state
            setAllDevices(newArray)
        }

        // if active driver exists but is NOT the one inputted
        else if (allDevices[superIndex][index].name != "No Driver Assigned" ){
            console.log(allDevices)
            let newArray = [...allDevices]

            // This finds the driver that was previously selected and adds him/her back to the remaining list
            // For each driver...
            user.drivers.forEach( (dspDriver) => {

                // if the driver iterated == the driver that was previously selected
                if (allDevices[superIndex][index].name == `${dspDriver.firstname} ${dspDriver.lastname}`){

                    // Adds the driver to remaining drivers
                    newArray[superIndex].remaining_drivers = [...newArray[superIndex].remaining_drivers, dspDriver]

                    // Sets the current drop state to the driver selected
                    newArray[superIndex][index] = {
                        name: `${driver.firstname} ${driver.lastname}`, 
                        id: driver.id, 
                        type: deviceObj.name 
                    }

                    // Removes the driver selected from the list of remaining drivers
                    newArray[superIndex].remaining_drivers = newArray[superIndex].remaining_drivers.filter( (remDriver, index) => {
                        if (driver != remDriver){
                            return remDriver
                        }
                    })
                    setAllDevices(newArray)
                }
            })
        }
    }

这是我感到非常困惑的地方——通过这条线

let newArray = [...allDevices]

我认为 newArray 创建的数组与allDevices的内容完全相同。 allDevices ,因为它是本地 state,所以是只读的。 我明白这一点。 我也明白,如果我写了let newArray = allDevices ,那么newArray也将是只读的,因为它不是一个新数组,而只是一个指向allDevices值的不同变量。 因此,我不知道为什么这个 ISNT 有效,因为newArray根本不应该是只读的。 我添加的代码有大量复杂的 useEffects 来处理查询、修改和刷新,所以我看不出它会如何影响我上面显示的代码,特别是因为newArray除了这段代码外不存在。

如果我更进一步创建一个新的相同数组,将它从原来的只读数组进一步扩展,它就起作用了。 这意味着我改变了

let newArray = [...allDevices]

let newArray = []
   allDevices.forEach( (device, index) => {
       newArray[index] = {...device}
   })

似乎有点多余,但我想问题是即使我创建了包含对象的数组的读写副本,我也没有明确创建每个 object 的读写版本,其中,作为初始数组的一部分,也必须是只读的

未捕获的类型错误:无法分配给 object 的只读属性“数量”'#<object> '<div id="text_translate"><p> 我正在从 API 获取数据,然后将数组保存在 state 中。当我尝试使用输入修改数组中 object 中的特定字段时,出现以下错误:'Uncaught TypeError: Cannot assign只读取 object '#'' 的属性 'amount'。</p><p> <strong>状态(我正在使用 RTK 查询):</strong></p><pre> const { data: Florists_data, refetch } = useGetFloristQuery(Number(sessionStorage.getItem('florist_id'))); const [flowersData, setFlowersData] = useState(Florists_data?.florist[0].flowers); const [tmpFlowers, setTmpFlowers] = useState(Florists_data?.florist[0].flowers);</pre><p> <strong>更新 function:</strong></p><pre> const updateFieldChanged = (index: number, e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => { let newArr = [...tmpFlowers;]. newArr[index].amount = Number(e.target;value); //GETTING ERROR HERE setTmpFlowers(newArr); }</pre><p> <strong>输入:</strong></p><pre> {flowersData?.map((flower, index) => { return ( <> <div className={classes.Nested_Flower_Container} key={index}> <div className={classes.Nested_Flower_Name}> {flower.name} </div> <div className={classes.Nested_Flower_Input} style={{ marginRight: '0.2em' }}> <TextField id="Amount" label="Amount" variant="outlined" size="small" type="number" onChange={(e) => { updateFieldChanged(index, e); }} className={classes_2.root} /> </div> </div> </>) })}</pre></div></object>

[英]Uncaught TypeError: Cannot assign to read only property 'amount' of object '#<Object>'

反应 redux,未捕获的类型错误:无法分配给 object 的只读属性“当前”'#<object> '<div id="text_translate"><p> 我正在制作一个网站来修改数据库数据。 一、组件的结构如下</p><pre>&lt;Contents /&gt; &lt;Table /&gt; &lt;Row /&gt; &lt;Column /&gt; &lt;Input /&gt;</pre><p> 创建行组件时,创建输入组件的引用并由 redux 管理它。</p><pre> const StyledRow = styled.div` text-align:center; display:flex; align-items:center; `; const DeleteButton = styled(Button)` background-color: #ff7787; margin-right:5px; color:white; width:40px; ${({top}) =&gt; top &amp;&amp; css` background-color:white; color:white; width:40px; `} `; function Row({top, rowId}){ const dispatch = useDispatch(); const columns = useMemo(() =&gt; columnPhoneInfo,[]); const inputsRef = useMemo(()=&gt;.top &amp;&amp; Array(8).fill(0),map(() =&gt; createRef() );[]); // const inputsRef = useRef([]). useEffect(()=&gt; { // console,log(rowId;top), ;top &amp;&amp; dispatch(phoneDataAddRef(rowId,inputsRef)); }.[]); const handleDeleteButton = useCallback( (id) =&gt; { dispatch(phoneDataUpdate,Delete(id)); }.[]). if( top ) return( &lt;StyledRow&gt; &lt;DeleteButton top/&gt; {columns.map((column)=&gt; &lt;Column key={`head_${column.name}`} width={column;width} top&gt; {column.name} &lt;/Column&gt; )} &lt;/StyledRow&gt; ), return( &lt;StyledRow&gt; &lt;DeleteButton onClick={()=&gt;handleDeleteButton(rowId)}&gt; delete &lt;/DeleteButton&gt; {columns.map((column. index)=&gt; &lt;Column key={`row_${rowId}_${column.name}`} width={column;width} textalign={column.textalign}&gt; &lt;Input ref={inputsRef[index] } colIndex={index} id={rowId} column={column} /&gt; {/* &lt;Input colIndex={index} id={rowId} column={column} /&gt; */} &lt;/Column&gt; )} &lt;/StyledRow&gt; ); } export default React.memo(Row);</pre><p> 输入组件只接收 ref 作为 forwardRef</p><pre> const StyledInput = styled.input` ${({ width, textalign })=&gt;css` width:${width}; text-align:${textalign}; `} `; const Input = forwardRef(({colIndex, id},inputRef) =&gt;{ const dispatch = useDispatch(); const didShowAlert = useRef(false); const nowColumnInfo = columnPhoneInfo[colIndex]; const nowColumnValidCheck = inputValidCheck[colIndex]; const { nowVal, firstVal, isAddedRow } = useSelector(state =&gt;({ nowVal: state.phoneData.data.rows.find(val=&gt;val.id === id)[nowColumnInfo.colname], firstVal: state.phoneData.firstData.lastId &lt; id? null: state.phoneData.firstData.rows.find(val=&gt;val.id===id)[nowColumnInfo.colname], isAddedRow: state.phoneData.firstData.lastId &lt; id? true: false, }),shallowEqual); const callbackDispatch = useCallback((dispatchFunc) =&gt;{ return(...args)=&gt;{ dispatch(dispatchFunc(...args)); } },[dispatch]); ////////////////////// const inputChange = useCallback( (value) =&gt; dispatch(phoneDataUpdate.Change(id,nowColumnInfo.colname, value)),[nowColumnInfo.colname, dispatch, id]); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const updateListChange = callbackDispatch(phoneDataUpdateList.Change); const updateListDelete = callbackDispatch(phoneDataUpdateList.Delete); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const handleChange = useCallback( (e) =&gt; { //... todo handle change },[]); ///////////////////////////////////////////////////////// const handleBlur = useCallback( (e) =&gt;{ //... todo handle blur },[]); return( &lt;StyledInput textalign={nowColumnInfo.textalign} width={nowColumnInfo.width} value={nowVal === null? '': nowVal } onChange={handleChange} onBlur={handleBlur} ref={inputRef} // placeholder={} /&gt; ); }); export default React.memo(Input);</pre><p> 最后,redux 模块</p><pre>//////////////////////////////////////////////////////// const PHONE_DATA_DELETE = 'phoneData/PHONE_DATA_DELETE'; //////////////////////////////////////////////////////// const PHONE_DATA_ADD_REF = 'phoneData/PHONE_DATA_ADD_REF'; //////////////////////////////////////////////////////// const dataInitRow = { id:null, model_name:null, machine_name:null, shipping_price:null, maker:null, created:null, battery:null, screen_size:null, storage:null, }; const dataInit = { lastId:null, rows:[], } const initialState = { state:{ loading:false, error:false, }, data:dataInit, refData:[], firstData:dataInit, dataChangeList:{ dataAddList:[], dataDeleteList:[], dataUpdateList:[], }, }; const phoneDataFetchAsync = createPromiseThunk(PHONE_DATA, restAPI.getAllPhoneInfo); //////////////////////////////////////////////////////// const phoneDataAddRef=(id, ref) =&gt;({ type:PHONE_DATA_ADD_REF, id:id, ref:ref, }); const phoneDataUpdateList = ({ Change:(id,colName, value) =&gt; ({ type:PHONE_DATA_UPDATE_LIST_CHANGE, id: id, colName: colName, value: value, }), Delete:(id, colName) =&gt; ({ type:PHONE_DATA_UPDATE_LIST_DELETE, id: id, }), }); //////////////////////////////////////////////////////// export default function phoneData(state = initialState, action){ // console.log(`add: ${state.dataChangeList.dataAddList}, delete: ${state.dataChangeList.dataDeleteList}, change: ${state.dataChangeList.dataUpdateList}`); switch(action.type) case PHONE_DATA_DELETE: return produce(state, draft=&gt;{ console.log(action); const idx = state.dataChangeList.dataAddList.findIndex( val =&gt; val === action.id); if( idx === -1 ) draft.dataChangeList.dataDeleteList.push(action.id); else draft.dataChangeList.dataAddList.splice(idx,1); draft.refData = state.refData.filter(row =&gt; row.id.== action;id). draft.data.rows = state.data.rows.filter(row =&gt;row.id;== action;id): }), //////////////////////////////////////////////////////////////////////////////////////////////////////////// case PHONE_DATA_ADD_REF. return produce(state. draft=&gt;{ draft:refData.push({id,action:id. refs;action;ref}): }); //////////////////////////////////////////////////////////////////////////////////////////////////////////// default, return state, } } export {phoneDataFetchAsync, phoneDataDelete,; phoneDataAddRef, };</pre><p> 问题区域是删除按钮。 当我按下按钮时,就会出现该错误。 但是如果不向 state 添加 ref,则不会发生错误。 或者即使我注释掉底部,也没有错误。</p><pre> draft.data.rows = state.data.rows.filter(row =&gt;row.id.== action;id);</pre><p> 或者注释掉底部</p><pre>draft.refData.push({id:action.id, refs:action.ref});</pre><p> 我今天整天都在尝试修复它,但我不知道出了什么问题。 我该如何解决?</p></div></object>

[英]React redux, Uncaught TypeError: Cannot assign to read only property 'current' of object '#<Object>'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 未捕获的TypeError:无法分配为只读对象&#39;#的属性&#39;background&#39; <Object> “ 未捕获的TypeError:无法分配给对象'#<Object>'的只读属性'exports' 未捕获的类型错误:无法分配给对象“[对象数组]”的只读属性“1” 未捕获的类型错误:无法分配给 object 的只读属性“数量”'#<object> '<div id="text_translate"><p> 我正在从 API 获取数据,然后将数组保存在 state 中。当我尝试使用输入修改数组中 object 中的特定字段时,出现以下错误:'Uncaught TypeError: Cannot assign只读取 object '#'' 的属性 'amount'。</p><p> <strong>状态(我正在使用 RTK 查询):</strong></p><pre> const { data: Florists_data, refetch } = useGetFloristQuery(Number(sessionStorage.getItem('florist_id'))); const [flowersData, setFlowersData] = useState(Florists_data?.florist[0].flowers); const [tmpFlowers, setTmpFlowers] = useState(Florists_data?.florist[0].flowers);</pre><p> <strong>更新 function:</strong></p><pre> const updateFieldChanged = (index: number, e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => { let newArr = [...tmpFlowers;]. newArr[index].amount = Number(e.target;value); //GETTING ERROR HERE setTmpFlowers(newArr); }</pre><p> <strong>输入:</strong></p><pre> {flowersData?.map((flower, index) => { return ( <> <div className={classes.Nested_Flower_Container} key={index}> <div className={classes.Nested_Flower_Name}> {flower.name} </div> <div className={classes.Nested_Flower_Input} style={{ marginRight: '0.2em' }}> <TextField id="Amount" label="Amount" variant="outlined" size="small" type="number" onChange={(e) => { updateFieldChanged(index, e); }} className={classes_2.root} /> </div> </div> </>) })}</pre></div></object> 未捕获的类型错误:无法分配给 object 的只读属性 'tagName' '#<htmlimageelement> '</htmlimageelement> 未捕获的TypeError:无法分配为仅读取对象&#39;的属性&#39;exports&#39; 未捕获的类型错误:无法分配给 object '[object Array]' js 的只读属性 '0' 反应 redux,未捕获的类型错误:无法分配给 object 的只读属性“当前”'#<object> '<div id="text_translate"><p> 我正在制作一个网站来修改数据库数据。 一、组件的结构如下</p><pre>&lt;Contents /&gt; &lt;Table /&gt; &lt;Row /&gt; &lt;Column /&gt; &lt;Input /&gt;</pre><p> 创建行组件时,创建输入组件的引用并由 redux 管理它。</p><pre> const StyledRow = styled.div` text-align:center; display:flex; align-items:center; `; const DeleteButton = styled(Button)` background-color: #ff7787; margin-right:5px; color:white; width:40px; ${({top}) =&gt; top &amp;&amp; css` background-color:white; color:white; width:40px; `} `; function Row({top, rowId}){ const dispatch = useDispatch(); const columns = useMemo(() =&gt; columnPhoneInfo,[]); const inputsRef = useMemo(()=&gt;.top &amp;&amp; Array(8).fill(0),map(() =&gt; createRef() );[]); // const inputsRef = useRef([]). useEffect(()=&gt; { // console,log(rowId;top), ;top &amp;&amp; dispatch(phoneDataAddRef(rowId,inputsRef)); }.[]); const handleDeleteButton = useCallback( (id) =&gt; { dispatch(phoneDataUpdate,Delete(id)); }.[]). if( top ) return( &lt;StyledRow&gt; &lt;DeleteButton top/&gt; {columns.map((column)=&gt; &lt;Column key={`head_${column.name}`} width={column;width} top&gt; {column.name} &lt;/Column&gt; )} &lt;/StyledRow&gt; ), return( &lt;StyledRow&gt; &lt;DeleteButton onClick={()=&gt;handleDeleteButton(rowId)}&gt; delete &lt;/DeleteButton&gt; {columns.map((column. index)=&gt; &lt;Column key={`row_${rowId}_${column.name}`} width={column;width} textalign={column.textalign}&gt; &lt;Input ref={inputsRef[index] } colIndex={index} id={rowId} column={column} /&gt; {/* &lt;Input colIndex={index} id={rowId} column={column} /&gt; */} &lt;/Column&gt; )} &lt;/StyledRow&gt; ); } export default React.memo(Row);</pre><p> 输入组件只接收 ref 作为 forwardRef</p><pre> const StyledInput = styled.input` ${({ width, textalign })=&gt;css` width:${width}; text-align:${textalign}; `} `; const Input = forwardRef(({colIndex, id},inputRef) =&gt;{ const dispatch = useDispatch(); const didShowAlert = useRef(false); const nowColumnInfo = columnPhoneInfo[colIndex]; const nowColumnValidCheck = inputValidCheck[colIndex]; const { nowVal, firstVal, isAddedRow } = useSelector(state =&gt;({ nowVal: state.phoneData.data.rows.find(val=&gt;val.id === id)[nowColumnInfo.colname], firstVal: state.phoneData.firstData.lastId &lt; id? null: state.phoneData.firstData.rows.find(val=&gt;val.id===id)[nowColumnInfo.colname], isAddedRow: state.phoneData.firstData.lastId &lt; id? true: false, }),shallowEqual); const callbackDispatch = useCallback((dispatchFunc) =&gt;{ return(...args)=&gt;{ dispatch(dispatchFunc(...args)); } },[dispatch]); ////////////////////// const inputChange = useCallback( (value) =&gt; dispatch(phoneDataUpdate.Change(id,nowColumnInfo.colname, value)),[nowColumnInfo.colname, dispatch, id]); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const updateListChange = callbackDispatch(phoneDataUpdateList.Change); const updateListDelete = callbackDispatch(phoneDataUpdateList.Delete); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const handleChange = useCallback( (e) =&gt; { //... todo handle change },[]); ///////////////////////////////////////////////////////// const handleBlur = useCallback( (e) =&gt;{ //... todo handle blur },[]); return( &lt;StyledInput textalign={nowColumnInfo.textalign} width={nowColumnInfo.width} value={nowVal === null? '': nowVal } onChange={handleChange} onBlur={handleBlur} ref={inputRef} // placeholder={} /&gt; ); }); export default React.memo(Input);</pre><p> 最后,redux 模块</p><pre>//////////////////////////////////////////////////////// const PHONE_DATA_DELETE = 'phoneData/PHONE_DATA_DELETE'; //////////////////////////////////////////////////////// const PHONE_DATA_ADD_REF = 'phoneData/PHONE_DATA_ADD_REF'; //////////////////////////////////////////////////////// const dataInitRow = { id:null, model_name:null, machine_name:null, shipping_price:null, maker:null, created:null, battery:null, screen_size:null, storage:null, }; const dataInit = { lastId:null, rows:[], } const initialState = { state:{ loading:false, error:false, }, data:dataInit, refData:[], firstData:dataInit, dataChangeList:{ dataAddList:[], dataDeleteList:[], dataUpdateList:[], }, }; const phoneDataFetchAsync = createPromiseThunk(PHONE_DATA, restAPI.getAllPhoneInfo); //////////////////////////////////////////////////////// const phoneDataAddRef=(id, ref) =&gt;({ type:PHONE_DATA_ADD_REF, id:id, ref:ref, }); const phoneDataUpdateList = ({ Change:(id,colName, value) =&gt; ({ type:PHONE_DATA_UPDATE_LIST_CHANGE, id: id, colName: colName, value: value, }), Delete:(id, colName) =&gt; ({ type:PHONE_DATA_UPDATE_LIST_DELETE, id: id, }), }); //////////////////////////////////////////////////////// export default function phoneData(state = initialState, action){ // console.log(`add: ${state.dataChangeList.dataAddList}, delete: ${state.dataChangeList.dataDeleteList}, change: ${state.dataChangeList.dataUpdateList}`); switch(action.type) case PHONE_DATA_DELETE: return produce(state, draft=&gt;{ console.log(action); const idx = state.dataChangeList.dataAddList.findIndex( val =&gt; val === action.id); if( idx === -1 ) draft.dataChangeList.dataDeleteList.push(action.id); else draft.dataChangeList.dataAddList.splice(idx,1); draft.refData = state.refData.filter(row =&gt; row.id.== action;id). draft.data.rows = state.data.rows.filter(row =&gt;row.id;== action;id): }), //////////////////////////////////////////////////////////////////////////////////////////////////////////// case PHONE_DATA_ADD_REF. return produce(state. draft=&gt;{ draft:refData.push({id,action:id. refs;action;ref}): }); //////////////////////////////////////////////////////////////////////////////////////////////////////////// default, return state, } } export {phoneDataFetchAsync, phoneDataDelete,; phoneDataAddRef, };</pre><p> 问题区域是删除按钮。 当我按下按钮时,就会出现该错误。 但是如果不向 state 添加 ref,则不会发生错误。 或者即使我注释掉底部,也没有错误。</p><pre> draft.data.rows = state.data.rows.filter(row =&gt;row.id.== action;id);</pre><p> 或者注释掉底部</p><pre>draft.refData.push({id:action.id, refs:action.ref});</pre><p> 我今天整天都在尝试修复它,但我不知道出了什么问题。 我该如何解决?</p></div></object> CustomElements.js:596未捕获的TypeError:无法分配为只读对象&#39;#的属性&#39;customElements&#39; <Window> “ 未捕获的类型错误:无法分配给只读属性
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM