何时加载与Flux的异步关系

时间:2015-04-24 02:38:23

标签: reactjs reactjs-flux flux

假设你有一个Pet组件显示宠物资源。您还拥有通过ownerId属性属于pet的所有者资源。您应该在Pet组件中加载所有者资源吗?

const Pet = React.createClass({
    getInitialState() {
        return {
            pet: PetStore.get(this.props.petId)
        };
    },

    componentDidMount() {
        PetStore.addChangeListener(this._onChange);
    },

    componentWillUnmount() {
        PetStore.removeChangeListener(this._onChange);
    },

    render() {
        var owner; // where should I initiate the ajax request to get owner? 

        return (
            <p>{owner.name}</p>
        );
    },

    onChange() {
        this.setState({
            pet: PetStore.get(this.props.petId)
        });
    }
});

2 个答案:

答案 0 :(得分:1)

正如Thilo所提到的,React文档建议您在componentDidMount中异步加载数据。在componentDidMount而不是componentWillMount上执行此操作的原因是,如果您在服务器上运行React以进行初始页面加载,那么componentWillMount将会执行,并且您不想在服务器上进行Ajax调用。

话虽如此,我建议您将数据获取逻辑移动到另一个组件(在React世界中通常称为视图控制器)。这意味着您可以使用两个组件,而不是让一个组件同时执行数据获取和渲染。一个是负责获取数据,另一个是渲染数据。您将该数据作为道具传递给视图控制器组件中的渲染组件。一个小例子是:

var Pet = React.createClass({
  render() {
    return (
      <p>Pet: {this.props.pet.name}</p>
      <p>Owner: {this.props.owner.name}</p>
    );
  }
});

var PetController = React.createClass({
  getInitialState() {
    return {
      pet: PetStore.get(this.props.petId),
      owner: null
    };
  },
  componentDidMount() {
    OwnerStore.getOwner(this.state.pet.ownerId)
      .then(owner => this.setState({owner: owner}));
  },
  render() {
    return <Pet pet={this.state.pet} owner={this.state.owner} />;
  }
});

这种分离给你的是更简单,更集中的组件。 Pet组件不必担心从何处获取数据,并且可以在从PetStore以外的某个位置获取数据的其他情况下重复使用它。 PetController组件仅关注数据获取和状态管理。为了使Pet组件更简单,您可以避免在获取所有者之前呈现它。类似的东西:

var PetController = React.createClass({
  getInitialState() {
    return {
      pet: PetStore.get(this.props.petId),
      owner: null
    };
  },
  componentDidMount() {
    OwnerStore.getOwner(this.state.pet.ownerId)
      .then(owner => this.setState({owner: owner}));
  },
  render() {
    if (this.state.pet && this.state.owner) {
      return <Pet pet={this.state.pet} owner={this.state.owner} />;
    } else {
      return <div className="spinner" />;
    }
  }
});

然后,您的Pet组件不必担心异步数据提取,因为在数据存在之前它不会被渲染。

答案 1 :(得分:0)

React documentation recommendscomponentDidMount中执行此操作。