Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/467.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 不可变地更新Redux状态_Javascript_Reactjs_React Redux_Sheetjs - Fatal编程技术网

Javascript 不可变地更新Redux状态

Javascript 不可变地更新Redux状态,javascript,reactjs,react-redux,sheetjs,Javascript,Reactjs,React Redux,Sheetjs,我正在改变状态不变,但这不起作用。基本上,我创建了一个函数来获取excel文件数据。此函数工作正常,但当我更新状态时,状态未更新 有什么想法或建议和我分享吗 以下是我的状态: tableData: [], productsData: [] 这是状态更新的减速器: case actionTypes.READ\u EXCEL: var excel1=[]; var excel2=[]; 持续承诺=新承诺((解决、拒绝)=>{ const fileReader=new fileReader();

我正在改变状态不变,但这不起作用。基本上,我创建了一个函数来获取excel文件数据。此函数工作正常,但当我更新状态时,状态未更新

有什么想法或建议和我分享吗

以下是我的状态:

tableData: [],
productsData: []
这是状态更新的减速器:

case actionTypes.READ\u EXCEL:
var excel1=[];
var excel2=[];
持续承诺=新承诺((解决、拒绝)=>{
const fileReader=new fileReader();
fileReader.readAsArrayBuffer(action.payload);
fileReader.onload=(e)=>{
const bufferArray=e.target.result;
常量wb={SheetNames:[],Sheets:{};
const ws1=XLSX.read(bufferArray,{type:“buffer”});
const ws2=XLSX.read(bufferArray,{type:“buffer”});
wb.SheetNames.push(“Sheet1”);
工作分解表[“表1”]=ws1;
wb.SheetNames.push(“Sheet2”);
工作分解表[“表2”]=ws2;
const data1=XLSX.utils.sheet_to_json(ws1);
const data2=XLSX.utils.sheet_to_json(ws2);
解析([data1,data2]);
}
fileReader.onerror=(错误)=>{
拒绝(错误);
};
})
承诺。然后((excelData)=>{
excel1=excelData[0];
excel2=excelData[1];
});
返回{
……国家,
tableData:excel1,
产品数据:excel2
}
违约:
}
返回状态;

}
新状态不会改变,因为您的承诺在返回语句后解析,这是由于承诺的性质而发生的,它不会阻止函数的执行,我建议使用一些中间件,如异步逻辑,如示例中的读取文件。最后,将excel数据传递给reducer以更新存储。

由于承诺是异步的,首先执行返回语句,然后将数据加载到excel1和excel2中

case actionTypes.READ\u EXCEL:
var excel1=[];
var excel2=[];
/*下面的行将创建一个承诺,该承诺将异步执行。
所以执行不会等到承诺被执行。
它将转到下一行,即Promise.then()*/
持续承诺=新承诺((解决、拒绝)=>{
const fileReader=new fileReader();
fileReader.readAsArrayBuffer(action.payload);
fileReader.onload=(e)=>{
const bufferArray=e.target.result;
常量wb={SheetNames:[],Sheets:{};
const ws1=XLSX.read(bufferArray,{type:“buffer”});
const ws2=XLSX.read(bufferArray,{type:“buffer”});
wb.SheetNames.push(“Sheet1”);
工作分解表[“表1”]=ws1;
wb.SheetNames.push(“Sheet2”);
工作分解表[“表2”]=ws2;
const data1=XLSX.utils.sheet_to_json(ws1);
const data2=XLSX.utils.sheet_to_json(ws2);
解析([data1,data2]);
}
fileReader.onerror=(错误)=>{
拒绝(错误);
};
})
/*在这里,我们只是附加了一个回调,以在承诺履行后执行。因此,执行会将指定的回调(excelData arrow函数)附加到promise.then()。
然后执行将移动到下一行,即返回语句。*/
承诺。然后((excelData)=>{
excel1=excelData[0];
excel2=excelData[1];
});
/*现在,由于承诺是异步的,并且将在fileReader读取数据后执行,因此excel1和excel2的值不会更新,而只包含空数组。
因此,您的状态将包含空数组*/
返回{
……国家,
tableData:excel1,
产品数据:excel2
}
违约:
}
返回状态;

}
您应该将异步操作移出减速器。使用reducer将数据写入树,而不是获取数据。看看关于处理副作用的恶作剧或传奇故事。正确!reducer应该是纯JavaScript函数,它应该返回更新状态。它不应该包含异步函数或副作用。在UI中,您可以使用dispatch函数执行异步操作,然后传递数据以更新状态。您可以使用
redux thunk
执行异步还原操作,这将解决您的问题是的,您是对的,但是redux thunks中间件呢。如何使用这些?下面是“export const addTodo”的示例。现在在您的示例中,我们可以将其编写为export const readExcel=(excelFile)=>{return dispatch=>{/*Promise和filereader logic*/Promise。然后((excelData)=>{dispatch({type:actionTypes.READ_EXCEL,payload:{excelData[0],excelData[1]}}})根据您的建议,单独的函数readExcel在您当前代码中的任何位置都不调用,您在哪里调用带有操作类型actionTypes的dispatch。READ_EXCEL?对不起,您的答案很好,但我无法实现它。您能更详细地说明这个答案吗?