Search code examples
javascriptreactjsgraphqlreact-apollographql-subscriptions

Need to use setstate() of data received from GraphQL subscription in react-apollo


I am trying to setState() of the GraphQL subscription Query that I am doing through react-apollo. My purpose is to store the complete the object that I received from GraphQL and save it into the state in the ComponentDidMount() method of the App.js file.

I have tried a lot of ways for it to work such as SubscribetoMore endpoint by react-apollo, but I think I am writing the wrong react code for it.

/App.js

const haveAnyFish = () => (
    <Subscription subscription={gql`${SUBSCRIPTION_SYNC}`} >
{({ loading, error, data }) => {
  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :</p>;
  return (
    <div>
      <div>{fishes(data)}</div>
    </div>
  );
}}
</Subscription>
);

/App.js

class App extends React.Component {
    state = {
      fishes: {},
      order: {}
    };
componentDidMount() {
    const fishes = (data) => {
        this.setState({ fishes: data });
    }
  }

Subscription Query

const SUBSCRIPTION_SYNC = `
    subscription syncState{
      cotd {
      _id_2
      name
      desc
      image
      price
      status
    }
  }`;

Solution

  • You no need to have componentDidMount in your case. You have defined function inside componentDidMount method and that can’t be accessed outside

    Change

       componentDidMount() {
            const fishes = (data) => {
                this.setState({ fishes: data });
            }
        }
    

    To

      fishes = data => {
            this.setState({ fishes: data });
      }
    

    And Change

        const haveAnyFish = () => (
            <Subscription subscription={gql`${SUBSCRIPTION_SYNC}`} >
              {({ loading, error, data }) => {
                  if (loading) return <p>Loading...</p>;
                  if (error) return <p>Error :</p>;
               return (
                 <div>
                    <div>{this.fishes(data)}</div>
                    </div>
                 );
               }}
             </Subscription>
            );
    

    To

         haveAnyFish = () => (
              <Subscription subscription={gql`${SUBSCRIPTION_SYNC}`} >
             {({ loading, error, data }) => {
              if (loading) return <p>Loading...</p>;
              if (error) return <p>Error :</p>;
                 return (
                    <div>
                      <div>{this.fishes(data)}</div>
                    </div>
                  );
               }}
            </Subscription>
          );
    

    You must be calling haveAnyFish function in your component without this so after above code change you need to call haveAnyFish function using this.haveAnyFish

    Also note that whenever you create functions inside a component they no need const before the function and if you want to access state or props inside those function you need to manually bind them or change them to arrow functions