Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting state in the Query component of react-apollo

Tags:

So, I'm trying to set an initial state for an edit component that gets data from the server and now should be editable in the component state. But when I try to do this:

<Query query={POST_QUERY} variables={{ id: this.props.match.params.id }}>     {({ data, loading, error }) => {       this.setState({ title: data.title }) 

I get stuck in an infinite loop since this is in render. Should I not use the component state with the query component? And if not, what is the alternative?

like image 245
Andreas Avatar asked May 20 '18 16:05

Andreas


People also ask

Does Apollo use React query?

The useQuery React hook is the primary API for executing queries in an Apollo application. To run a query within a React component, call useQuery and pass it a GraphQL query string.

Can I use React query with GraphQL?

Because React Query's fetching mechanisms are agnostically built on Promises, you can use React Query with literally any asynchronous data fetching client, including GraphQL!


2 Answers

Whatever component needs this data as state should be rendered inside the Query component, and then have the data passed down to it as a prop. For example:

class MyComponent extends React.Component {   constructor (props) {     this.state = {       title: props.post.title     }   } }  <Query query={POST_QUERY} variables={{ id: this.props.match.params.id }}>   {({ data, loading, error }) => {     <MyComponent post={data.post}/>   }} </Query> 
like image 170
Daniel Rearden Avatar answered Oct 14 '22 00:10

Daniel Rearden


You can use the onCompleted prop on Querycomponent to set the state. See below example:

class MyComponent extends React.Component {   constructor (props) {     this.state = {       isFirstRender: true       title: props.post.title     }   }      setTitle = title => {     if (this.state.isFirstRender){         this.setState({title, isFirstRender: false})     }   }      render () {     return <Query              query={POST_QUERY}              variables={{ id: this.props.match.params.id }}               onCompleted={data => this.setTitle(data.post.title)}            >       {({ data, loading, error }) => {         <MyComponent post={data.post}/>       }}     </Query>   } } 

Edit:

As the bug of onCompleted firing multiple times has been resolved in the latest version of react-apollo, we can now simply do:

  ...      <Query         query={POST_QUERY}         variables={{ id: this.props.match.params.id }}         onCompleted={data => this.setState({ title: data.post.title})}      >       {({ data, loading, error }) => {          <MyComponent post={data.post}/>       }}     </Query>   )   ... 
like image 29
Eesa Avatar answered Oct 13 '22 22:10

Eesa