在此处输入代码我正在通过我的app.js文件中的提供者包装为整个React应用提供Redux全局状态。
除了“当前配置文件”之外,我没有任何其他状态可以访问。
这里是 组件 :
import React, { Fragment, useEffect } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { loadTargetProfiles, loadCurrentProfile } from "../../actions/profile";
const Friends = ({
loadCurrentProfile,
loadTargetProfiles,
profile: { currentProfile, targetProfiles, targetProfilesAreLoading },
}) => {
useEffect(() => {
loadTargetProfiles();
loadCurrentProfile();
}, []);
console.log(currentProfile);
return (
...
};
Friends.propTypes = {
loadTargetProfiles: PropTypes.func.isRequired,
loadCurrentProfile: PropTypes.func.isRequired,
profile: PropTypes.object.isRequired,
};
const mapStateToProps = (state) => ({
profile: state.profile,
});
export default connect(mapStateToProps, {
loadCurrentProfile,
loadTargetProfiles,
})(Friends);
这是loadCurrentProfile 动作 ,负责提供currentProfile状态。
export const loadCurrentProfile = () => async (dispatch) => {
try {
const res = await api.get("/profile/current");
dispatch({
type: LOAD_CURRENT_PROFILE,
payload: res.data,
});
} catch (err) {
dispatch({
type: PROFILE_ERROR,
payload: { msg: err.response.statusText, status: err.response.status },
});
}
};
这是 减速器
的相关部分const initialState = {
currentProfile: null,
targetProfile: null,
targetProfiles: [],
currentProfileIsLoading: true,
targetProfileIsLoading: true,
targetProfilesAreLoading: true,
error: {},
};
//
// Export Reducer
export default function (state = initialState, action) {
const { type, payload } = action;
switch (type) {
case LOAD_CURRENT_PROFILE:
return {
...state,
currentProfile: payload,
currentProfileIsLoading: false,
};
这是受到攻击的 API :
router.get("/current", auth, async (req, res) => {
try {
const profile = await Profile.findOne({
user: req.user.id,
}).populate("user", ["_id", "username", "registerdate"]);
if (!profile) {
return res
.status(400)
.json({ msg: "There is no profile for this user." });
}
res.json(profile);
} catch (err) {
console.error(err.message);
res.status(500).send("Server Error...");
}
});
这是 控制台
这是currentProfile状态的展开状态:
例如,当我尝试进入currentProfile状态时
const Friends = ({
loadCurrentProfile,
loadTargetProfiles,
profile: { currentProfile: {
avatar
}, targetProfiles, targetProfilesAreLoading },
}) => {
useEffect(() => {
loadTargetProfiles();
loadCurrentProfile();
}, []);
console.log(avatar);
它给我错误:
TypeError:无法读取null的属性“头像”
这是Redux Dev Tools屏幕截图:
修复:
我(在声明函数后)通过访问内部状态(暂时)摆脱了错误。
const Friends= ({
profile: { currentProfileIsLoading },
currentProfile,
}) => {
currentProfile && console.log(currentProfile.avatar);
,它现在可以使用,但肯定不是最优雅的解决方案。有没有一种方法可以在函数声明中添加此防护,以将状态设置在一个地方?
答案 0 :(得分:3)
问题:targetProfiles
和targetProfilesAreLoading
在您的状态下均为真实值,但是currentProfile
为空,直到GET解析。您无法访问空对象的avatar
属性。
您可以为profile
提供一些默认参数值,但这只有在profile
未定义的情况下才有效,空值将作为已定义的值。
const Friends = ({
loadCurrentProfile,
loadTargetProfiles,
profile: {
currentProfile = {},
targetProfiles,
targetProfilesAreLoading
},
}) => {
useEffect(() => {
loadTargetProfiles();
loadCurrentProfile();
}, []);
console.log(currentProfile);
return (
...
};
您还可以在可能未定义/空的对象上使用防护措施
currentProfile && currentProfile.avatar
另一种选择是使用状态选择器库(例如reselect
),该状态选择器库允许您提取/增强/派生/等...作为道具传递的状态值。这还允许您设置状态的默认/后备值。它与redux很好地配对。