递归数据和组件,稍后获取会引发错误 [英] Recursive data & components, later fetches throwing an error

查看:42
本文介绍了递归数据和组件,稍后获取会引发错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先是我的graphql数据模型:

First off my graphql data model:

type Human {
  id: !String,
  name: !String,
  children: [Human]
}

我是atm使用的唯一路由(中继路由配置):

The only route (relay route config) I'm atm using:

class extends Relay.Route {
  static queries = {
    human: () => Relay.QL`query RootQuery { viewer }`
  };
  static routeName = 'AppHomeRoute';
}

列表组件:

class HumanList extends Component {
  render() {
    let {children} = this.props.human;

    let subListsHTML = human ? children.map(child => (
      <HumanListItem key={child.id} human={child}/>
    )) : '';

    return <ul>{subListsHTML}</ul>;
  }
}

export default Relay.createContainer(HumanList, {
  fragments: {
    human: () =>  Relay.QL`
      fragment on Human {
        children {
          id,
          ${HumanListItem.getFragment('human')}
        }
      }
    `
  }
});

列表项组件:

class HumanListItem extends Component {
  state = {expanded: false};

  render() {
    let {human} = this.props;

    let sublistHTML = '';
    if (this.state.expanded) {
      sublistHTML = <ul><HumanList human={human}/></ul>;
    }

    return (
      <li>
        <div onClick={this.onClickHead.bind(this)}>{human.name}</div>
        {sublistHTML}
      </li>
    );
  }

  onClickHead() {
    this.props.relay.setVariables({expanded: true});
    this.setState({expanded: true});
  }

}

HumanListItem.defaultProps = {viewer: {}};

export default Relay.createContainer(HumanListItem, {

  initialVariables: {
    expanded: false
  },

  fragments: {
    human: (variables) =>  Relay.QL`
      fragment on Human {
        name,
        ${HumanList.getFragment('human').if(variables.expanded)}
      }
    `
  }

});

对于根列表来说,这运行得很好.但是,当我单击ListItem并将其展开时,会出现以下错误:

Which runs fine for the root list. But as soon as I click on a ListItem and it is expanded, I get the following error:

警告:RelayContainer:预期道具'human'提供的'HumanList'是Relay提取的数据.除非您有意传递符合该组件片段形状的模拟数据,否则这可能是一个错误.

我对此没有多大意义,因为我传递的数据不是模拟的而是由Relay直接获取的,就像在HumanList组件中可以看到的那样.

I can't make much sense of it, since the data I'm passing is not mocked but directly fetched by Relay as can be seen in the HumanList comp.

推荐答案

该错误表明< HumanList> 在数据准备就绪之前正在呈现.

The error indicates that the <HumanList> is being rendered before its data is ready.

class HumanListItem extends Component {
  onClickHead() {
    this.props.relay.setVariables({expanded: true});
    this.setState({expanded: true});  // <-- this causes the component to re-render before data is ready
  }

您可以查看变量的当前值,而不是使用状态:

Rather than using state, you can instead look at the current value of the variables:

class HumanListItem extends Component {
  // no need for `state.expanded`

  render() {
    let {human} = this.props;

    let sublistHTML = '';
    if (this.props.relay.variables.expanded) {
      // `variables` are the *currently fetched* data
      // if `variables.expanded` is true, expanded data is fetched
      sublistHTML = <ul><HumanList human={human}/></ul>;
    }

    return (
      <li>
        <div onClick={this.onClickHead.bind(this)}>{human.name}</div>
        {sublistHTML}
      </li>
    );
  }

  onClickHead() {
    this.props.relay.setVariables({expanded: true});
    // no need for `setState()`
  }

}

HumanListItem.defaultProps = {viewer: {}};

export default Relay.createContainer(HumanListItem, {

  initialVariables: {
    expanded: false
  },

  fragments: {
    human: (variables) =>  Relay.QL`
      fragment on Human {
        name,
        ${HumanList.getFragment('human').if(variables.expanded)}
      }
    `
  }

});

这篇关于递归数据和组件,稍后获取会引发错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆