繁体   English   中英

未捕获的TypeError:无法分配给对象'#<Object>'的只读属性'exports'

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

我有错误:“未捕获的TypeError:无法分配给对象'#'的只读属性'exports'”。 在build.js中,此错误在“module.exports = main;”行中。 哪里出错了? 我的模块:

这是我的主文件script.js

const showContent = require('./modules/showContent');
const main = require('./modules/screens/main');
const about = require('./modules/screens/about');
const blog = require('./modules/screens/blog');
const contacts = require('./modules/screens/contacts');
const gallery = require('./modules/screens/gallery');

$(document).ready(function() {
  console.log(main);
  showContent(main);
    $(document).on("click", "a", (e) => {
        if ( $(this).hasClass('active') ) return;

        $("a").removeClass('active');
        $(this).addClass('active');

        $(".slide").slideUp(800);

        const self = this;
        setTimeout(() => showContent($(self).attr('id')), 800);
    });
});

main.js

const getElementFromTemplate = require('../getElementFromTemplate');
const showContent = require('../showContent');

const main = getElementFromTemplate(`<div>
        <h2>Добро пожаловать на Фиджи</h2>
        <img src="images/img03.jpg" alt="img03">
        <p><b>Фиджи</b> - название государства и архипелага из 332 островов, на которых это государство находится: на юго-западе Тихого океана, среди других островов и архипелагов Меланезии - правда, расстояние между этими частицами суши составляет сотни и тысячи километров. Острова архипелага Фиджи коралловые и вулканические; примерно 1/3 их нежилые, однако это и привлекает внимание желающих уединиться по разным причинам - влюбленных пар, молодоженов, романтиков и просто любителей нетронутой природы.</p>
      </div>
      <div>
        <h2>Климат Фиджи: мягкие тропики</h2>
        <img src="images/img04.jpg" alt="img04">
        <p>Климат влажный тропический, но сильной жары нет ни летом, в сезон дождей - около 26 ° C, ни в сухой сезон - около 23 ° C: здесь комфортно чувствуют себя и взрослые, и дети. Правда, бывают и более высокие температуры - 28-34 ° C, но в ночи всегда становится прохладнее.</p>
        <p>Для отдыха обычно рекомендуется выбирать период с мая по декабрь, когда дождей почти нет. Погода отличается в разных частях архипелага: так, на южных берегах основных островов дожди идут чаще и больше высокая влажность воздуха.</p>
      </div>
      <div>
        <h2>Пляжи на Фиджи</h2>
        <img src="images/img05.jpg" alt="img05">
        <p>Больше всего туристов «привлекается» на остров Вити-Леву, крупнейший в архипелаге Фиджи. Здесь любой может найти себе место по душе и по карману: есть и первоклассные отели и недорогие гостиницы. Пляжи тянутся более чем на 100 км - их называют Коралловым берегом; территория острова - более 10 000 км, и на побережье расположено множество различных курортов, от фешенебельных до тихих и незаметных. Для семейного отдыха хороший пляж Paradise, тихий и спокойный, с мелким белым песком и почти не затронутым «окультуриванием»: пальмы рядом растут прямо у берега и скрыться от жаркого солнца - не проблема, что особенно актуально для семей с детьми. Однако, об удобных головные уборы, солнечные очки и солнцезащитные средства следует позаботиться вовремя: загар на Фиджи очень красивый, но получить солнечные ожоги, в том числе и находясь в воде, можно «в два счета». Взрослые могут найти себе здесь массу развлечений, от дайвинга до рыбалки с арендой катера.</p>
      </div>
      <div>
        <h2>Экскурсии и памятные места на Фиджи</h2>
        <img src="images/img06.jpg" alt="img06">
        <p>Кажется, что памятников на Фиджи не может быть много, но их, исторических и природных, наберется немало. Сигатока - песчаные дюны, является уникальным местом: на Фиджи везде зелень, а здесь - волнообразные холмы из песка до 60 м высотой - считается, что они формировались миллионы лет. История местности не менее интересна, чем пейзаж: здесь создан археологический парк и открыт музей. Археологи находят вещи, которым около 3000 лет, а здешние захоронения еще старше.</p>
        <p>На Фиджи очень много национальных парков и заповедников, за охраной которых постоянно следят местные власти: ведь нетронутая природа - главное богатство этой небольшой и гостеприимной страны с приветливыми и веселыми жителями.</p>
      </div>`);

module.exports = main;

showContent.js

const showContent = (contentTemplate) => {
  const content = document.querySelector(`main`);
  content.innerHTML = ``;
  content.appendChild(contentTemplate);
};

module.exports = showContent;

webpack.config.js

module.exports = {
    entry: "./script",
    output: {
        filename: "build.js"
    }
};

更多信息 - webpack / issues / 4039

原因

在指示Babel不转换模块语法之后,这个问题对我产生了新的影响。 它只在尝试在ES模块中使用CommonJS样式module.exports时发生。 这可以通过简单地替换所有module.exports = ...来导出默认值来修复......在适用的情况下,因为这似乎等同于旧的Babel风格的ES模块转换。 (请注意,使用require导入此模块可能会为您提供一个默认键而不是默认导出本身的选项,因此最好立即在整个代码库中进行切换。)

通过jchv @ github

在.babelrc中设置

删除.babelrc中的“modules:false”

preset-es2015选项 - 模块

“amd”| “umd”| “systemjs”| “commonjs”| false,默认为“commonjs”。
启用将ES6模块语法转换为其他模块类型。
将此设置为false将不会转换模块。

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

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