假设我有 2 <Logs/>
成分。它们仅在其父级 <Block/>
时显示已被点击。每个<Block/>
只有一个<Logs/>
但会有很多<Blocks/>
在页面上。
class Block extends React.Component {
toggleExpanded() {
this.setState({
isExpanded: !this.state.isExpanded
});
}
render() {
let blockId = // ...
return (
<div>
<button type="button" onClick={() => this.toggleExpanded()}>Toggle</button>
{this.state.isExpanded && <Logs blockId={blockId} />}
</div>
);
}
}
export default Block;
作为<Logs/>
创建完成后,我想使用 Redux 从服务器获取数据。可能有很多<Logs/>
有一天,我不想一开始就加载所有数据,只加载需要的数据。
class Logs extends React.Component {
componentDidMount() {
if (!this.props.logs) {
this.props.fetchBlockLogs(this.props.blockId);
}
}
render() {
return (this.props.logs && this.props.logs.length)
? (
<ul>
{this.props.logs.map((log, i) => <li key={i}>{log}</li>)}
</ul>
)
: (
<p>Loading ...</p>
);
}
}
SupportLogs.defaultProps = {
logs: null
}
const mapStateToProps = (state) => ({
logs: state.support.logs
});
const mapDispatchToProps = (dispatch, ownProps) => ({
fetchBlockLogs: (blockId) => {
dispatch(ActionTypes.fetchBlockLogs(blockId));
}
});
export default connect(mapStateToProps, mapDispatchToProps)(SupportLogs);
目前,当我切换一位家长时 <Block/>
关闭然后重新打开,数据会被记住。这是一个很好的功能 - 数据不会经常更改,并且本地缓存是加速页面速度的好方法。我的问题是,当我打开第二个 <Block/>
时,数据来自第一个<Logs/>
显示。
我的问题是:如何为 <Logs/>
的新实例加载新数据?
我每次都必须重新加载数据吗?如果是这样,我可以清除logs
吗?属性以便我恢复加载动画?
最佳答案
也许考虑将商店中的日志更改为一个对象,其中加载的日志由 block ID 键入:
logs: {
'someBlockId': [
'some logline',
'some other logline'
]
]
让你的reducer通过 block id将任何请求的日志添加到这个对象中,这样当你请求它们时,它们就会被缓存在你的存储中(顺便说一句,我真的很喜欢你的组件调度一个 Action 来触发其他地方的数据获取,作为副作用,而不是在组件内部执行获取数据:))。
此 reducer 假设所获取的数据在一个操作中分派(dispatch),表示它已收到特定 block 的日志,{type: 'UPDATE_LOGS', blockId: 'nicage', returnedLogsForBlock: ['oscar ', '获胜', ' Actor ']}
logsReducer: (prevState, action) => {
switch(action.type)
case 'UPDATE_LOGS':
return Object.assign({}, prevState, {
[actions.blockId]: action.receivedLogsForBlock
})
default: return prevState
}
}
在您的组件中,您现在可以通过 id 查找它们。如果日志对象中没有定义所需的 block ,那么您知道您需要发送加载操作,并且还可以同时显示加载器
class Logs extends React.Component {
componentDidMount() {
const {logs, blockId} = this.props
if (!logs[blockId]) {
this.props.fetchBlockLogs(blockId);
}
}
render() {
const {logs, blockId} = this.props
return (logs && logs[blockId]) ? (
<ul>
{logs[blockId].map((log, i) => <li key={i}>{log}</li>)}
</ul>
) : (
<p>Loading ...</p>
)
}
}
这还有一个额外的好处,即logs[blockId]
是未定义
,意味着未加载
,因此可以区分需要加载的内容。已加载,并且已经加载但有空日志,您的原始版本会误认为需要加载
关于javascript - 如何在不同的 ReactJS 组件实例中拥有不同的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47653075/