繁体   English   中英

未捕获的类型错误:无法分配给 object 的只读属性 'tagName' '#<htmlimageelement> '</htmlimageelement>

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

每当我在浏览器中单击<li>元素内的空闲空间时,我都会收到 window 警报,显示标题 (gridMainTitle)。 这没关系。 但是在这个<li>元素上,我设置了一个小网格布局,对齐图像和一些文本。 我现在的问题是,如果我单击位于网格内部和 li 元素上的图像 object,我还想发出警报。 但我只收到一条错误消息: Uncaught TypeError: Cannot assign to read only property 'tagName' of object '#<HTMLImageElement>'

 this.listRoot = this.mainView.querySelector("ul"); this.listRoot.onclick = (evt) => { const selectedLi = this.find(evt.target); if (selectedLi) { alert("clicked on: " + this.getTitleFromLi(selectedLi)); } else { alert("something went completely wrong..."); } } } find(el) { if (el.tagName == "LI") { return el; } else if (el.tagName = "...") { // DIV or IMG doesn't really work. return el; } else if (el.tagName = "UL") { return null; } else if (el.parentNode) { return this.find(el.parentNode); } else { return null; } } getTitleFromLi(liElement) { return liElement.getElementsByClassName("gridMainTitle") [0].textContent; }
 <main class="tiles"> <ul> <li class="grid-container"> <div class="gridImageObject"> <img src="imagefile" class="align-left"/> </div> <div class="gridMainTitle"> <p class="align-left">Some Text</p> </div> </li> </ul> </main>

您使用了单个等号(赋值)而不是双等号(比较)。 例如

if (el.tagName = "...")

应该

if (el.tagName == "...")

未捕获的类型错误:无法分配给 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>'

反应 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.

相关问题 未捕获的类型错误:无法分配给 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> 未捕获的TypeError:无法分配为只读对象&#39;#的属性&#39;background&#39; <Object> “ 未捕获的TypeError:无法分配给对象'#<Object>'的只读属性'exports' 未捕获的类型错误:无法分配给对象“[对象数组]”的只读属性“1” 未捕获的TypeError:无法读取null的属性&#39;tagName&#39; 未捕获的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> Angular.JS Uncaught TypeError:无法分配给只读属性
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM