递归数据和组件,稍后获取抛出错误

Posted

技术标签:

【中文标题】递归数据和组件,稍后获取抛出错误【英文标题】:Recursive data & components, later fetches throwing an error 【发布时间】:2015-12-06 11:56:19 【问题描述】:

首先是我的 graphql 数据模型:

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

我正在使用的唯一路由(中继路由配置):

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 并展开它,就会出现以下错误:

Warning: RelayContainer: Expected prop 'human' supplied 'HumanList' to be data fetched by Relay. This is likely an error unless you are purposely passing in mock data that conforms to the shape of this component's fragment.

我无法理解它,因为我传递的数据不是模拟的,而是由 Relay 直接获取的,这可以在 HumanList 组合中看到。

【问题讨论】:

【参考方案1】:

该错误表明&lt;HumanList&gt; 在其数据准备好之前正在呈现。

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
  

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

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

);

【讨论】:

非常感谢!设置状态和变量已经感觉很奇怪。应该把它当作一个提示......我仍然有一个错误,但我认为这与我的 graphql 实现有关,所以这已经解决了!

以上是关于递归数据和组件,稍后获取抛出错误的主要内容,如果未能解决你的问题,请参考以下文章

Dash Plotly Graph(Dash 核心组件抛出错误)

Vue组件的高级用法

使用分页数据时 Livewire 抛出错误

这个 c 递归函数有啥原因会产生这个页面错误吗?

showBottomSheet 抛出错误,抱怨没有脚手架

使用实体框架获取存储过程输出参数抛出映射错误:数据读取器与指定的不兼容