简体   繁体   English

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

[英]How can I have different data in different ReactJS Component instances?

Let's say I have 2 <Logs/> components. 假设我有2个<Logs/>组件。 They're only displayed when their parent <Block/> has been clicked. 仅在单击其父<Block/>时显示它们。 Each <Block/> only has one <Logs/> but there will be many <Blocks/> on the page. 每个<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;

As the <Logs/> is created, I want to get data from the server using Redux. 创建<Logs/> ,我想使用Redux从服务器获取数据。 There could be a lot of <Logs/> some day so I don't want to load in all data to begin with, only data as needed. 某天可能会有很多<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);

Currently, as I toggle one parent <Block/> closed and then re-opened, the data is remembered. 当前,当我切换一个父<Block/>关闭并重新打开时,数据会被记住。 That's a nice feature - the data won't change often and a local cache is a nice way to speed up the page. 这是一个不错的功能-数据不会经常更改,本地缓存是加快页面速度的不错方法。 My problem is that as I toggle open a second <Block/> , the data from the first <Logs/> is shown. 我的问题是,当我打开第二个<Block/> ,显示了第一个<Logs/>的数据。

My question is: how can I load in new data for a new instance of <Logs/> ? 我的问题是: 如何为<Logs/>的新实例加载新数据?

Do I have to re-load the data each time and, if so, can I clear the logs property so that I get the loading animation back? 我是否必须每次都重新加载数据,如果可以,是否可以清除logs属性以便重新获得加载动画?

Maybe think about changing the logs in your store to be an object with logs loaded into it keyed by block id: 也许考虑将您商店中的日志更改为一个对象,并加载其中的日志,并以块ID为键:

logs: {
 'someBlockId': [
   'some logline', 
   'some other logline'
 ]
]

Have your reducer add any requested logs to this object by block id, so as you request them they get cached in your store (by the way I really like that your component dispatches an action to trigger data fetching elsewhere as a side effect, rather than having the fetch data performed inside the component :) ). 让减速器通过块ID将任何请求的日志添加到此对象,以便在您请求它们时将它们缓存在商店中(顺便说一句,我真的很喜欢您的组件调度一个操作来触发其他地方获取数据的行为,而不是副作用)在组件内部执行获取数据:))。

This reducer assumes that the resulting fetched data is dispatched in an action to say it has received the logs for a particular block, {type: 'UPDATE_LOGS', blockId: 'nic cage', receivedLogsForBlock: ['oscar', 'winning', 'actor']} 该化简器假设在一个动作中调度了所获取的数据,以说它已接收到特定块的日志, {type: 'UPDATE_LOGS', blockId: 'nic cage', receivedLogsForBlock: ['oscar', 'winning', 'actor']}

logsReducer: (prevState, action) => {
  switch(action.type)
    case 'UPDATE_LOGS':
      return Object.assign({}, prevState, {
        [actions.blockId]: action.receivedLogsForBlock
      })
    default: return prevState
  }
}

And in your component you can now look them up by id. 现在,您可以在组件中按ID查找它们。 If the required block is not defined in the logs object, then you know you need to send the action for loading, and can also show loader in meantime 如果未在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>
      )
  }

}

This has the added bonus of logs[blockId] being undefined meaning not loaded , so it is possible to distinguish between what needs to be loaded and what has already loaded but has empty logs, which your original would have mistaken for requiring a load 这增加了undefinedlogs[blockId]含义,即not loaded ,因此可以区分需要加载的内容和已加载但有空日志的内容,您的原始日志会误认为需要加载

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在reactjs的不同组件中编写链接和路由 - How can I write Link and Route in different component in reactjs 如何更新代表相同数据的两个不同的React组件实例? - How to update two different React component instances that represent the same data? 如何在 React 应用程序中为不同的组件设置不同的背景颜色? - How can I have different background color for different component in a React app? 如何在模拟数据中有多个相同类型的不同实例 - how to have mutliple different instances of the same type in mock data 对具有不同数据的同一组件进行ReactJS视图处理 - ReactJS view handling on same component with different data ReactJS-用不同的数据重新渲染相同的组件? - ReactJS - rerender same component with different data? 如何用不同的数据渲染相同的 Angular 组件? 我有一个基于 url 部分呈现的 Angular 组件 - How to render a same Angular component with different data? I have an Angular component which renders based on the part of the url 如何在 map() 中显示不同的组件 - How can i display different component in map() 在Ember中,如何在多个地方使用的组件中具有不同的html? - In Ember how can I have different html in a component used in multiple places? 如何在Reactjs中制作组件实例 - How to make component instances in Reactjs
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM