GraphQL HOC弄乱了对孩子的引用反应

时间:2018-07-17 08:04:26

标签: reactjs graphql apollo react-apollo

我在我的项目中使用React和Apollo。

我在组件MenuModal中得到了这个

onClick = () => {
    console.log(this.child)
    this.child.onSubmit(); // do stuff
};

render() {
    return (
        <Modal.Content scrolling>
            <MenuEdit
                ref={ref => (this.child = ref)} // Using ref to access it's properties
                selectedValues={selectedValues}
                match={match}
                menu={menu}
            />

我的组件MenuEdit具有在类中定义的功能:

onSubmit = values => {
    console.log('calling inner form submit', values);
    if (this.child) {
        this.child.submitFromOutside();
    }
};

我应该可以从onSubmit打电话给MenuModal吧?

但是我目前正在得到这个: enter image description here

当我在this.child函数中使用console.log onClick时,我可以看到:

enter image description here 因此,这里没有onSubmit函数。看到GraphQL时,我想知道是否与使用graphQL HOC导出组件有关。

export default compose(
    graphql(UPDATE_MENU, { name: 'updateMenu' }),
    withApollo,
    withRouter
)(MenuEdit);

当我将其更改为:

export default MenuEdit;

我可以看到我的功能 enter image description here

所以我想知道如何编写导出文件,以便仍然可以在孩子中访问函数。谢谢。

2 个答案:

答案 0 :(得分:0)

HOC将您的组件包装到另一个组件中。您可以在React devtools中看到它。您将看到该组件在包裹的组件周围呈现了一个组件。像这样

<Apollo(ChildComponent)>
  <ChildComponent />
</Apollo>

您的引用然后指向Apollo(ChildComponen)元素实例。

您在这里所做的事情对我来说似乎是一种反模式。在React中,我们通常不对渲染的元素(有时是DOM元素)调用函数。这个想法更确切地说是,孩子通过将其作为属性来接受父母的职能。在您的情况下,最好的办法是摆脱引用,并在组件链中向上移动状态和动作。或者,您可以在react-apollo中使用新的render prop style

答案 1 :(得分:0)

Apollo存储库为解决此问题做出了贡献... https://github.com/apollographql/react-apollo/pull/410

像这样withApollo(Component, { withRef: true })包装组件导出将公开您的子方法。可通过ref.current.wrappedInstance访问。