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?
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.
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!
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>
You can use the onCompleted
prop on Query
component 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> ) ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With