Javascript 如何在不同的组件实例中拥有不同的数据?

Javascript 如何在不同的组件实例中拥有不同的数据?,javascript,reactjs,redux,Javascript,Reactjs,Redux,假设我有两个组件。它们仅在单击其父项时显示。每个页面只有一个,但页面上会有很多 class Block extends React.Component { toggleExpanded() { this.setState({ isExpanded: !this.state.isExpanded }); } render() { let blockId = // ... re

假设我有两个组件。它们仅在单击其父项时显示。每个页面只有一个,但页面上会有很多

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;
创建时,我希望使用Redux从服务器获取数据。将来可能会有很多数据,所以我不想一开始就加载所有数据,只加载需要的数据

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);
目前,当我切换一个父项关闭然后重新打开时,数据会被记住。这是一个很好的特性-数据不会经常更改,而本地缓存是一个很好的加速页面的方法。我的问题是,当我切换第二个打开时,第一个打开的数据会显示出来

我的问题是:如何为的新实例加载新数据


是否每次都必须重新加载数据?如果是,是否可以清除logs属性以恢复加载动画?

也许可以考虑将存储中的日志更改为一个对象,其中加载的日志由块id键控:

logs: {
 'someBlockId': [
   'some logline', 
   'some other logline'
 ]
]
让您的reducer按块id将任何请求的日志添加到此对象,以便在您请求它们时,它们会被缓存在您的存储中,我非常喜欢您的组件将一个操作作为副作用发送到别处触发数据提取,而不是在组件内执行提取数据:

此reducer假定结果获取的数据在一个动作中被调度,表示它已收到特定块的日志,{type:'UPDATE_logs',blockId:'nic cage',receivedLogsForBlock:['oscar','winning','actor']}

现在,您可以在组件中按id查找它们。如果logs对象中未定义所需的块,则您知道需要发送操作以进行加载,同时还可以显示loader

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>
      )
  }

}

这增加了日志[blockId]未定义即未加载的额外功能,因此可以区分需要加载的日志和已经加载但有空日志的日志,而您的原始日志可能会误认为需要从您提供的日志加载,我认为blockId对于您单击的任何内容都是相同的,因此它总是只获取1个blockId的数据。我认为您应该使用blockId来管理要获取的数据以及何时获取数据。如果您不想获取父组件中的所有数据,那么最好在块或日志组件中设置一个fetchData。当一个块被扩展时,它应该检索所述日志的数据,并获取该块ID。很好,很简单-我喜欢它。我还需要一段时间才能测试,但我会测试,可能会接受这个答案。很乐意帮忙,希望一切顺利!
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>
      )
  }

}