亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

不可變地更新 Redux 狀態

不可變地更新 Redux 狀態

繁星淼淼 2023-04-27 10:50:09
我正在一成不變地改變狀態,但這不起作用。基本上,我創建了一個函數來獲取 excel 文件數據。此功能完美運行,但當我更新狀態時,狀態未更新。任何想法或任何建議與我分享這是我的狀態:tableData: [], productsData: []這是狀態更新的減速器:case actionTypes.READ_EXCEL:            var excel1 = [];            var excel2 = [];            const promise = new Promise((resolve, reject) => {                const fileReader = new FileReader();                fileReader.readAsArrayBuffer(action.payload);                fileReader.onload = (e) => {                    const bufferArray = e.target.result;                    const wb = { SheetNames:[], Sheets:{} };                    const ws1 = XLSX.read(bufferArray, {type: "buffer"}).Sheets.Sheet1;                    const ws2 = XLSX.read(bufferArray, {type: "buffer"}).Sheets.Sheet2;                    wb.SheetNames.push("Sheet1");                    wb.Sheets["Sheet1"] = ws1;                                        wb.SheetNames.push("Sheet2");                    wb.Sheets["Sheet2"] = ws2;                    const data1 = XLSX.utils.sheet_to_json(ws1);                    const data2 = XLSX.utils.sheet_to_json(ws2);                    resolve([ data1, data2 ]);                }                fileReader.onerror = (error) => {                    reject(error);                };            })            promise.then((excelData) => {                excel1 = excelData[0];                excel2 = excelData[1];                            });            return {                ...state,                tableData: excel1,                productsData: excel2                }        default:    }    return state; }在獲取狀態值和狀態值未更新的 UI 中:const mapStateToProps = (state) => { return {  items: state.tableData,     <---  products: state.productsData    <--- };}
查看完整描述

2 回答

?
湖上湖

TA貢獻2003條經驗 獲得超2個贊

新狀態不會改變,因為你的 Promise 在 return 語句之后解析,這是因為 Promise 的性質,它不會阻止你的函數的執行,我建議使用像 redux-thunk 這樣的中間件來實現異步邏輯在您的示例閱讀文件中。最后,您將 excel 數據傳遞給 reducer 以更新商店。



查看完整回答
反對 回復 2023-04-27
?
慕田峪4524236

TA貢獻1875條經驗 獲得超5個贊

由于承諾是異步的,因此首先執行返回語句,然后將數據加載到 excel1 和 excel2 中。


case actionTypes.READ_EXCEL:

            var excel1 = [];

            var excel2 = [];

            /*Below line will create a promise, which will be executed asynchronously. 

            So the execution will not wait until promise is executed.

            It will go to next line which is Promise.then()*/ 


            const promise = new Promise((resolve, reject) => {

                const fileReader = new FileReader();

                fileReader.readAsArrayBuffer(action.payload);

                fileReader.onload = (e) => {

                    const bufferArray = e.target.result;

                    const wb = { SheetNames:[], Sheets:{} };

                    const ws1 = XLSX.read(bufferArray, {type: "buffer"}).Sheets.Sheet1;

                    const ws2 = XLSX.read(bufferArray, {type: "buffer"}).Sheets.Sheet2;


                    wb.SheetNames.push("Sheet1");

                    wb.Sheets["Sheet1"] = ws1;

                    

                    wb.SheetNames.push("Sheet2");

                    wb.Sheets["Sheet2"] = ws2;


                    const data1 = XLSX.utils.sheet_to_json(ws1);

                    const data2 = XLSX.utils.sheet_to_json(ws2);

                    resolve([ data1, data2 ]);

                }

                fileReader.onerror = (error) => {

                    reject(error);

                };

            })

           /*here as well the we're just attaching a callback to promise to be executed after promise is fulfilled. so execution will attach the specified callback (excelData arrow function) to promise.then(). 

           And then execution will move to next line which is return statement.*/ 

            promise.then((excelData) => {

                excel1 = excelData[0];

                excel2 = excelData[1];

                

            });

             /*Now here, as the promises are async and will be executed after the fileReader reads data, the values of excel1 and excel2 are not updated but only contain the empty array. 

            And hence your state will have empty arrays in it*/

            return {

                ...state,

                tableData: excel1,

                productsData: excel2

                }

        default:

    }

    return state; 

}


您可以做一件事,將使用 fileReader 讀取數據的代碼編寫到一個函數中,該函數將在您當前在代碼中放置 dispatch 語句的位置執行。在 promise.then() 中,您可以使用加載的數據調用 dispatch 。所以你的新代碼可能看起來像這樣


// separate function for reading the data

function readExcel(excelData) {

    return dispatch=>{

    const promise = new Promise((resolve, reject) => {

        const fileReader = new FileReader();

        fileReader.readAsArrayBuffer(excelData);

        fileReader.onload = (e) => {

            const bufferArray = e.target.result;

            const wb = {

                SheetNames: [],

                Sheets: {}

            };

            const ws1 = XLSX.read(bufferArray, {

                type: "buffer"

            }).Sheets.Sheet1;

            const ws2 = XLSX.read(bufferArray, {

                type: "buffer"

            }).Sheets.Sheet2;


            wb.SheetNames.push("Sheet1");

            wb.Sheets["Sheet1"] = ws1;


            wb.SheetNames.push("Sheet2");

            wb.Sheets["Sheet2"] = ws2;


            const data1 = XLSX.utils.sheet_to_json(ws1);

            const data2 = XLSX.utils.sheet_to_json(ws2);

            resolve([data1, data2]);

        }

        fileReader.onerror = (error) => {

            reject(error);

        };

    })

    promise.then((excelData) => {

        excel1 = excelData[0];

        excel2 = excelData[1];

        // Dispatching only after we get the data from fileReader

        dispatch({

            type: actionTypes.READ_EXCEL,

            payload: {

                excel1,

                excel2

            }

        })

      });

   }

}


// In reducer function

case actionTypes.READ_EXCEL:

    return {

        ...state,

        tableData: action.payload.excel1,

        productsData: action.payload.excel2

    }


查看完整回答
反對 回復 2023-04-27
  • 2 回答
  • 0 關注
  • 165 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號