Search code examples
javascriptreactjsgraphqlapolloreact-apollo

refetchQueries in Mutation Component of React Apollo Client is not working?


I have a <Query /> in my Home.js file

Home.js

<Query
      query={GET_TODOS_BY_PRODUCT}
      variables={{ id: state.get("selectedProduct.id"), completed: true }}
    >
      {({ data: { product } }) => {
        return <Main todos={product.todos} hashtag={product.hashtag} />;
      }}
</Query>

In my Main.js file I have <Mutation /> component -

Main.js

<Mutation
    key={v4()}
    mutation={SWITCH_SELECTED_PRODUCT}
    refetchQueries={() => {
        console.log("refetchQueries", product.id);
        return {
            query: GET_TODOS_BY_PRODUCT,
            variables: { id: product.id }
        };
    }}
>
{switchSelectedProduct => (
        <Product
            onClick={() => {
                switchSelectedProduct({
                    variables: { id: product.id, name: product.name }
                });
            }}
            highlight={
                data.selectedProduct
                    ? product.name === data.selectedProduct.name
                    : i === 0
            }
        >
            <Name>{product.name}</Name>
        </Product>
    )}
</Mutation>

When switchSelectedProduct is called inside <Mutation /> component, it runs refetchQueries as I see the console.log("refetchQueries", product.id); statement but I don't see the updated results in the <Query /> component in Home.js file.

How do I tell <Query /> component in Home.js to get notified when refetchQueries is run in Main.js file?

Any suggestions?


Solution

  • I solved it with some help. There is apparently a bug in refetchQueries as it does not update data from another component. But refetchQueries was not needed at all.

    I wrapped my Home component with another Query like:

    Home.js

    <Query
        query={GET_ALL_PRODUCTS}
        variables={{ id: state.get("user.id") }}
    >
        {({ data: { user } }) => {
            const { id, name } = user.products ? user.products[0] : [];
            return <Main id={id} name={name} />;
        }}
    </Query>
    

    Then I also wrapped my Main component with another Query so it changes state when mutation is applied. This way you don't need refetchQueries at all. Just wrap your Mutation or Query component when Mutation from another or same component is performed.

    Main.js

    <Query query={GET_SELECTED_PRODUCT}>
        <Mutation
                key={v4()}
                mutation={SWITCH_SELECTED_PRODUCT}
        >
        {switchSelectedProduct => (
                        <Product
                                onClick={() => {
                                        switchSelectedProduct({
                                                variables: { id: product.id, name: product.name }
                                        });
                                }}
                                highlight={
                                        data.selectedProduct
                                                ? product.name === data.selectedProduct.name
                                                : i === 0
                                }
                        >
                                <Name>{product.name}</Name>
                        </Product>
                )}
        </Mutation>
    </Query>