嗨,我是 react 和 redux 的新手,我遇到以下问题,将 clientName 属性添加到 mapStateToProps 中的 Proposals 数组会出现以下错误:“TypeError:无法读取未定义的属性‘名称’”,我试过了很多事情我真的找不到解决办法。
const ProposalsPage = ({ proposals, clients, loading, loadProposals,loadClients }) => {
useEffect(() => {
if (proposals.length === 0) {
loadProposals().catch((error) => {
alert("loading proposals failed " + error);
});
}
if (clients.length === 0) {
loadClients().catch((error) => {
alert("loading clients failed " + error);
});
}
}, [proposals]);
...
...
...
};
ProposalsPage.propTypes = {
proposals: PropTypes.array.isRequired,
clients: PropTypes.array.isRequired,
loadProposals: PropTypes.func.isRequired,
saveProposal: PropTypes.func.isRequired,
loading: PropTypes.bool.isRequired,
loadClients: PropTypes.func.isRequired,
};
function mapStateToProps(state) {
return {
proposals:
state.clients.length === 0
? []
: state.proposals.map(proposal => {
return {...proposal,
clientName: state.clients.find(c => c.id === proposal.id).name
};
}),
clients: state.clients,
loading: state.apiCallsInProgress > 0,
};
}
const mapDispatchToProps = {
loadProposals,
saveProposal,
loadClients
};
export default connect(mapStateToProps, mapDispatchToProps)(ProposalsPage);
答案 0 :(得分:0)
问题是代码找不到具有给定提案 ID 的客户端。 你确定这条线是正确的吗?
state.clients.find(c => c.id === proposal.id).name
我假设 client.id
与 proposal.id
无关。
我认为类似于client.proposalId
:
state.clients.find(c => c.proposalId === proposal.id).name
答案 1 :(得分:0)
问题似乎在线上发生了:
clientName: state.clients.find(c => c.id === proposal.id).name
您看到“无法读取未定义的属性‘名称’”错误,因为在这种情况下,执行 state.clients.find(c => c.id === proposal.id)
的结果是为某些值返回 undefined
。
这可能是因为没有任何 clients
实例与 find()
proposal.id
条件匹配(只有一个不匹配,足以使错误被抛出),或者是因为 state.clients
数据在您要评估 state
数据时尚未加载到 state.proposals
上。
此问题的一种解决方案是首先检查是否存在 clients
数据,然后尝试将其映射到 proposals
数据,或者使用空值作为后备,例如null
或 undefined
。
例如:
return {
proposals:
state.clients.length === 0
? []
: state.proposals.map(proposal => {
const proposalClient = state.clients.find(c => c.id === proposal.id)
if(!proposalClient) {
// not found, so we can't map the 'clientName' right now, keep the proposal as is
return proposal
}
// client found, return proposal with clientName
return { ...proposal, clientName: proposalClient.name };
}),
clients: state.clients,
loading: state.apiCallsInProgress > 0,
};