首先我的 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 comp 中所示。