2015-09-10 5 views
3

Во-первых мой 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, как это видно на Comp.

ответ

10

Ошибка указывает, что <HumanList> визуализируется до того, как данные будут готовы.

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

}); 
+1

Спасибо много! Уже было странно задавать состояние и переменные. Должен был принять это как подсказку ... У меня все еще есть ошибка, но я думаю, что это связано с моей реализацией graphql, так что это решение! –