javascript - Apollo client truy vấn và lưu trữ dữ liệu khi kết nối với nhiều thành phần
Tôi có 3 thành phần khác nhau sử dụng cùng một câu truy vấn graphql. Ví dụ này sẽ là câu truy vấn GET_USERS. Nó được sử dụng khi tìm người dùng để nhắn tin trong tab nhắn tin tương ứng và cũng khi mời người dùng thực hiện các hành động và gắn thẻ họ khi tạo bài viết.
Vấn đề tôi đang gặp phải và cố gắng tìm cách xử lý là không phải lúc nào chỉ có một cái được hiển thị cùng một lúc. Người dùng có thể nhấp vào tab tin nhắn và sau đó đi đánh dấu một người dùng trong tab bài đăng. Vấn đề: khi họ trở lại tab tin nhắn, bây giờ nó đã được hiển thị lại với trạng thái của truy vấn được gọi từ việc gắn thẻ.
Có gợi ý nào về cách thiết lập trạng thái với Apollo và các truy vấn nói chung để tránh vấn đề này không. Cuối cùng thì backend của tôi chỉ là một 'route' hoặc hàm resolve cho hành động cụ thể đó.
CHỈNH SỬA Để biết thêm thông tin. Cách tôi biết rằng tôi có thể giải quyết vấn đề này là sử dụng yêu cầu axios đến endpoint graphql và lưu phản hồi vào useState cục bộ cho thành phần đó. Nếu tôi làm điều này cho từng nơi khác nhau trong ứng dụng sử dụng thông tin, chúng sẽ vẫn tách rời và không chia sẻ cùng một trạng thái chính xác.
Nhưng để rõ ràng, tôi đang cố gắng giải quyết việc này trong khi sử dụng Apollo nếu có thể.
Câu trả lời #1
Bạn có thể sử dụng kết hợp giữa trạng thái cục bộ (useState) và useLazyQuery. Theo như tôi hiểu, bạn có nhiều thành phần (hoặc màn hình, tab, bất cứ thứ gì) được gắn cùng một lúc, ví dụ ScreenA và ScreenB. Trong mỗi thành phần đó, bạn truy vấn GET_USERS, nhưng khi kết quả truy vấn của bạn cập nhật ở ScreenB, bạn không muốn kết quả ở ScreenA cũng bị cập nhật.
Với useLazyQuery điều này có thể trông như sau:
- Tạo một hook tùy chỉnh để dễ dàng tái sử dụng trên các thành phần
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}
}
- Trong ScreenA, sử dụng hook và lấy truy vấn:
const ScreenA = () => {
const {queryGetUsers, users} = useLazyGetUsers()
return (
<TouchableOpacity onPress={() => queryGetUsers()}>
<Text>Get users</Text>
</TouchableOpacity>
)
}
- Trong ScreenB, cũng sử dụng hook.
Lưu ý rằng bạn có thể gọi queryGetUsers bất cứ khi nào bạn muốn, khi component được gắn, khi nhấn TouchableOpacity hoặc bất cứ lúc nào.
const ScreenB = () => {
const {queryGetUsers, users} = useLazyGetUsers()
useEffect(() => {
queryGetUsers()
}, [])
return (
...
)
}
- Sử dụng
userstheo ý bạn. Nếu bạn gọiqueryGetUserstrong ScreenA, nó sẽ không cập nhật giá trị củauserstrong ScreenB.
Đây không phải là giải pháp Apollo 100% nhưng nó sử dụng trạng thái cục bộ rất ít và các hook làm cho việc tái sử dụng rất dễ dàng. Tôi hy vọng điều này giải quyết được vấn đề của bạn!
Bạn có thể đọc thêm về useLazyQuery tại đây:
- https://www.apollographql.com/docs/react/data/queries/#executing-queries-manually
- https://www.apollographql.com/docs/react/api/react/hooks/#uselazyquery
