使用异步数据初始化组件 [英] Initialize component with Async data

查看:84
本文介绍了使用异步数据初始化组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试弄清楚在 react + redux + thunk 中为我的选择框如何以及在何处加载数据(即在我的操作上调用调度).我不确定它是否应该放在我的 App 容器的构造函数中,或者我应该将它加载到我的组件中(在我的示例中:MyDropdown")

我的主应用:

从'../components/mydropdown'导入MyDropdown;//我应该在这里导入我的动作然后...//import { loadData } from '../actions';类 App 扩展组件 {使成为() {返回 (<div className="页面内容"><div className="选项栏">//在 MyDropdown 中将其作为 PROP 发送...<MyDropdown/>

);}}导出默认应用程序;

我的组件

//或者.. 我应该在我的 MyDropdown 组件中加载它吗?从'../actions'导入{loadData};类 MyDropdown 扩展组件 {//如果我在加载时加载它,我该怎么做?使成为() {返回(<选择>{renderOptions()}</选择>);}}

我在我的 App 类中尝试了 componentDidMount(),但它似乎不起作用.将初始化数据和操作调用放在那里似乎是有意义的,因为它将全部集中,而不是在我的子组件中调用操作.此外,我将有多个选择框需要在启动时加载,所以我的 App 类可能会增长很多,这是正确的方法吗?我不确定最佳实践是什么,因为我才刚刚开始学习 React.

解决方案

您应该将数据组件与表示组件分开(参见帖子 此处).

因此,在您的小示例中,应该向 MyDropdown 传递渲染组件所需的所有数据.这意味着在 App(或实际渲染视图的组件的某些父组件)中获取数据.

由于您正在使用 React 和 Redux,react-redux 库提供了一个帮助程序函数来生成容器,用于获取您的演示组件所需的数据.

为此,将 App 更改为:

import { connect } from 'react-redux'从'../components/mydropdown'导入MyDropdown;从'../actions'导入{loadData};//这个类没有导出类 App 扩展组件 {componentDidMount() {this.props.loadData()}使成为() {返回 (<div className="页面内容"><div className="选项栏"><MyDropdown data={this.props.data}/>

);}}函数 mapStateToProps(state) {const { 数据 } = 状态返回 {数据}}函数 mapDispatchToProps(dispatch) {返回 {加载数据(){调度(加载数据())}}}//导出一个包装App的容器导出默认连接(mapStateToProps, mapDispatchToProps)(App);

或者,您可以保持 App 不变并将 MyDropdown 更改为:

import { connect } from 'react-redux'从'../actions'导入{loadData};//导出这个只允许使用展示组件导出类 MyDropdown 扩展组件 {componentDidMount() {this.props.loadData()}使成为() {返回(<选择>{renderOptions(this.props.data)}</选择>);}}函数 mapStateToProps(state) {const { 数据 } = 状态返回 {数据}}函数 mapDispatchToProps(dispatch) {返回 {加载数据(){调度(加载数据())}}}//默认情况下,导出包装展示组件的容器导出默认连接(mapStateToProps,mapDispatchToProps)(MyDropdown);

在这两种情况下,查看最后实际导出的默认值.它不是组件;它是 connect 的返回.该函数包装您的展示组件并返回一个容器,该容器负责为展示组件获取数据和调用操作.

这为您提供了所需的分离,并允许您灵活地使用演示组件.在任一示例中,如果您已经拥有渲染 MyDropdown 所需的数据,则只需使用演示组件并跳过数据获取!

您可以在 Redux 文档此处中查看完整示例.

I'm trying to figure out how and where to load the data (ie call dispatch on my action) for my select box in react + redux + thunk. I'm not sure if it should go in the constructor of my App container, or should i load it inside my component (in my example: "MyDropdown")

My main App:

import MyDropdown from '../components/mydropdown';
// Should i import my action here and then...
// import { loadData } from '../actions';

class App extends Component {
  render() {
    return (
      <div className="page-content">
        <div className="option-bar">
          // SEND it as a PROP inside MyDropdown... 
          <MyDropdown />
        </div>
      </div>
    );
  }
}
export default App;

My Component

// OR.. Should i load it in my MyDropdown component here?
import { loadData } from '../actions';

class MyDropdown extends Component {
  // If i load it here on load, how do i do it?
  render() {
    return(
      <select>
         {renderOptions()}
      </select>
    );
  }
}

I've tried componentDidMount() inside my App class, but it didnt seem to work. It seems to make sense to put the initialize data and call to actions there as it'll be all centralized, instead of calling actions inside my child components. Also, i'll have multiple select boxes that need to be loaded on startup, so my App class might grow quite a bit, is that the correct way to do it? I'm not sure what the best practice is as i've only just started learning react.

解决方案

You should separate data components from presentation components (see post here).

So in your small example, MyDropdown should be passed all the data it needs in order to render the component. That would mean fetching the data in App (or some parent component of the component actually rendering the view.

Since you're working with React and Redux, the react-redux library provides a helper function to generate containers that fetch the data required for your presentation component.

To do that, change App to:

import { connect } from 'react-redux'
import MyDropdown from '../components/mydropdown';
import { loadData } from '../actions';

// This class is not exported
class App extends Component {
  componentDidMount() {
    this.props.loadData()
  }
  render() {
    return (
      <div className="page-content">
        <div className="option-bar">
          <MyDropdown data={this.props.data}/>
        </div>
      </div>
    );
  }
}

function mapStateToProps(state) {
  const { data } = state
  return {
    data
  }
}

function mapDispatchToProps(dispatch) {
  return {
    loadData(){
      dispatch(loadData())
    }
  }
}

// Export a container that wraps App
export default connect(mapStateToProps, mapDispatchToProps)(App);

Alternatively, you could keep App the same and change MyDropdown to:

import { connect } from 'react-redux'
import { loadData } from '../actions';

// Exporting this allows using only the presentational component
export class MyDropdown extends Component {
  componentDidMount() {
    this.props.loadData()
  }
  render() {
    return(
      <select>
         {renderOptions(this.props.data)}
      </select>
    );
  }
}

function mapStateToProps(state) {
  const { data } = state
  return {
    data
  }
}

function mapDispatchToProps(dispatch) {
  return {
    loadData(){
      dispatch(loadData())
    }
  }
}

// By default, export the container that wraps the presentational component
export default connect(mapStateToProps, mapDispatchToProps)(MyDropdown);

In both cases, look at what is actually being exported as default at the end. It's not the component; it's the return of connect. That function wraps your presentational component and returns a container that is responsible for fetching the data and calling actions for the presentational component.

This gives you the separation you need and allows you to be flexible in how you use the presentation component. In either example, if you already have the data you need to render MyDropdown, you can just use the presentation component and skip the data fetch!

You can see a full example of this in the Redux docs here.

这篇关于使用异步数据初始化组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆