Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
409 views
in Technique[技术] by (71.8m points)

react native - Apollo client queries and data store when connected to multiple components

I have 3 different components that use the same graphql query. This example would be GET_USERS query. This is used when looking for users to message in the messaging respective tab and also when inviting users for actions and tagging them when creating posts.

the problem I'm having and trying to figure out how to handle is that its not always the case that only one is rendered at a time. A user might click the message tab and then go to tag a user in the post tab. Problem: when he comes back to the message tab it now has re-rendered with the state of the query that was called from the tagging.

Any suggestions on how to set up the state with Apollo and the queries in general to avoid this issue. At the end of the day my backend is one "route" or resolve function for the specific action.

EDIT For further information. The way I know I could solve it is to use axios request to the graphql endpoint and store the response in local useState for that component. If I did this for each of the different places in the app that use the information they would remain decoupled and not share the exact same state.

But to be clear I am trying to solve this while using Apollo if possible.

question from:https://stackoverflow.com/questions/65661743/apollo-client-queries-and-data-store-when-connected-to-multiple-components

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You could use a combination of local state (useState) and useLazyQuery. From what I understand you have multiple components (or screens, tabs, whatever) mounted at the same time, say ScreenA and ScreenB. In each of them you query GET_USERS, but when your query results update in ScreenB, you don't want to also update the results in ScreenA.

With useLazyQuery this could look like this:

  1. Create a custom hook for easy reusability across components
export const useLazyGetUsers = () => {
  const [users, setUsers] = useState()

  const [queryGetUsers] = useLazyQuery(GET_USERS, {
    onCompleted: (data) => setUsers(data.users),
    onError: (error) => console.log('onError', { error }), // handle errors as you wish
    fetchPolicy: "cache-and-network", // or whatever you want
  })

  return {queryGetUsers, users}
}
  1. In ScreenA, use the hook and fetch the query:
const ScreenA = () => {
  const {queryGetUsers, users} = useLazyGetUsers()
  
  return (
    <TouchableOpacity onPress={() => queryGetUsers()}>
      <Text>Get users</Text>
    </TouchableOpacity>
  )
}
  1. In ScreenB, also use the hook.

Note that you can call queryGetUsers whenever you want, on mount, on TouchableOpacity press, or whenever.

const ScreenB = () => {
  const {queryGetUsers, users} = useLazyGetUsers()
  
  useEffect(() => {
    queryGetUsers()
  }, [])

  return (
    ...
  )
}
  1. Use users as you wish. If you call queryGetUsers in ScreenA, it will not update the value of users in ScreenB.

This is not a 100% Apollo solution but it makes minimal use of local state and the hooks makes it very easy to reuse. I hope this solves your issue!

You can read more about useLazyQuery here:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...