我正在开发一款应用程序来自学React和Redux,在尝试访问已添加到存储中的变量时遇到了问题。
我可以使用console.log将数据添加到存储对象并验证数据是否存在,但当我试图深入到我想要访问的实际变量时,我收到了一个错误:"TypeError:无法读取未定义的属性'state'"。
查看状态时,我可以看到状态在那里:{"customerInfo":[],"loginInfo":[],"storeStatus":[{"status":false}]}
但是尝试访问state.storeStatus[0](例如:state.storeStatus[0].status(中的任何内容时会返回未定义的错误。
如果我想将该变量分配给一个新变量,以便在某些条件呈现中使用,那么我应该尝试访问该变量,有没有其他方法?
storeStatusReducers.js
import deepFreeze from 'deep-freeze'
const state = [];
const storeStatusReducer = (state = true, action) => {
switch(action.type) {
case 'STORE_STATUS_UPDATE':
state = [];
return [...state, action.data]
default:
return state
}
}
export const updateStoreStatusAction = (status) => {
return {
type: 'STORE_STATUS_UPDATE',
data: {
status
}
}
}
deepFreeze(state)
export default storeStatusReducer;
home.js
import React, { useState, useEffect } from "react";
import axios from "axios";
import { updateStoreStatusAction } from '../reducers/storeStatusReducers'
import { useSelector, useDispatch } from 'react-redux'
const storeInfo = {
storeId : "1337",
storeStatus: true
}
const HomePage = (props) => {
const dispatch = useDispatch()
const storeStatusData = useSelector(state => state.storeStatus);
let payload = {
storeId: storeInfo.storeId,
};
useEffect(() => {
axios({
url: "/api/get-test-data/" + storeInfo.storeId,
method: "GET",
data: payload,
})
.then((data) => {
console.log("data.data.storeStatusPayload", JSON.stringify(data.data.storeStatusPayload))
updateStoreStatus(data.data.storeStatusPayload);
})
.catch((error) => {
console.log("changeStoreStatus: Internal server error");
});
}, []);
const updateStoreStatus = (updatedStoreStatus) => {
dispatch(updateStoreStatusAction(updatedStoreStatus));
};
//This works and produces: {"status":false}
console.log("storeStatusData", JSON.stringify(storeStatusData[0]))
// This does not when trying to access status
console.log("storeStatusData", JSON.stringify(storeStatusData[0].status))
return (
<div>
<main>
<h1>Test App</h1>
</main>
</div>
);
};
export default HomePage;
更新:这现在起作用了。谢谢
更新的home.js
import React, { useState, useEffect } from "react";
import axios from "axios";
import { updateStoreStatusAction } from '../reducers/storeStatusReducers'
import { useSelector, useDispatch } from 'react-redux'
const storeInfo = {
storeId : "1337",
storeStatus: true
}
const HomePage = (props) => {
const dispatch = useDispatch()
const storeStatusData = useSelector(state => state.storeStatus);
let payload = {
storeId: storeInfo.storeId,
};
useEffect(() => {
axios({
url: "/api/get-test-data/" + storeInfo.storeId,
method: "GET",
data: payload,
})
.then((data) => {
console.log("data.data.storeStatusPayload", JSON.stringify(data.data.storeStatusPayload))
updateStoreStatus(data.data.storeStatusPayload);
})
.catch((error) => {
console.log("changeStoreStatus: Internal server error");
});
}, []);
const updateStoreStatus = (updatedStoreStatus) => {
dispatch(updateStoreStatusAction(updatedStoreStatus));
};
//This works and produces: {"status":false}
console.log("storeStatusData", JSON.stringify(storeStatusData[0]))
// This does not when trying to access status
console.log("storeStatusData", JSON.stringify(storeStatusData[0].status))
const renderLoadingBar = () => {
if (storeStatusData[0] ) {
return (
<div>
loaded
</div>
);
} else {
return (
// table container
<div>
loading
</div>
);
}
};
return (
<div>
<main>
<h1>Test App</h1>
<div>{renderLoadingBar()}</div>
</main>
</div>
);
};
export default HomePage;
由于效果是异步运行的,因此数据在初始渲染时将不可用。这意味着试图访问不存在的数组元素上的道具会导致你的应用程序崩溃。
您的初始日志语句出现以正常工作,这很可能是因为它在初始渲染中为undefined
,但在第二次渲染中为预期值。另一方面,第二个console.log
语句会立即失败,并且永远不会进行后续渲染。
为了防止这种问题发生,一种常见的模式是使用短路评估。例如:
const HomePage = (props) => {
// (initial component code here)
// Only log if the array element exists
storeStatusData[0] && console.log("storeStatusData", JSON.stringify(storeStatusData[0].status))
return (
<div>
<main>
<h1>Test App</h1>
</main>
</div>
);
};