GraphQL 突變
GraphQL 突變
GraphQL 選擇器 會執行初始查詢,並訂閱任何變更。您可以使用 useMutation()
和 commitMutation()
等 Relay API 來更新伺服器上的狀態。這些變更也會同步,導致 Recoil GraphQL 選擇器更新。這讓您可以使用選擇器作為本機快取,同時將伺服器視為真實來源。
突變回應應該會選擇您希望在更新時,由伺服器傳回的資料,以便能更新本機用戶端狀態。此需求是必要的,如此根據這些資料的其他 GraphQL 查詢和 Recoil 選擇器才會使用新的狀態重新呈現。建議使用 GraphQL 片段,來確保查詢和突變會傳回相同的資料。對於比較複雜的更新,您可能需要使用 updater
選項。您還可以使用 optimisticResponse
或 optimisticUpdater
,在從伺服器取得突變回應之前,更新本機狀態。如果出現錯誤,樂觀更新會回復成原來的狀態。總之,請確定突變使用與查詢和選擇器相同的 Relay 環境。
function MyComponent(props) {
const user = useRecoilValue(userQuery(props.userID));
const [commitEvent] = useMutation(graphql`
mutation UserMutation($input: UsertNameChangeData!) {
user_mutation(data: $input) {
user {
id
name
}
}
}
`);
return (
<div>
<h1>{user.name}</h1>
<button onClick={() => {
commitEvent({
variables: {
input: {
id: props.userID,
name: 'New Name',
},
},
});
}}>Change Name</button>
</div>
);
}
寫入快取
您可使用的另一種更新狀態的模式是將 Recoil 選取器當作伺服器的區域寫入快取。它是一個可寫的選取器,因此區域更新會立即反映在 UI 中。如果您提供GraphQL 突變資訊,則更新選取器也會與伺服器一起啟動突變。
const userState = graphQLSelector({
key: 'User',
environment: relayFBEnvironmentKey,
query: graphql`
query UserQuery($eventID: ID!, $clientID: ClientID!) {
user(id: $eventID, client_id: $clientID) {
name
timestamp
}
}
`,
variables: id => ({get}) => ({id, clientID: get(clientIDAtom}),
mapResponse: data => data.user,
mutations: {
mutation: graphql`
mutation UserMutation($input: UserNameChangeData!) {
user_mutation(data: $input) {
user {
id
name
}
}
}
`,
variables: newUserData => id => ({input: {id, name: newUserData.name}}),
},
});
function MyComponent() {
const [user, setUser] = useRecoilState(userState);
return (
<div>
<h1>{user.name}</h1>
<button onClick={() => {
setUser(user => ({...user, name: 'New Name'}));
}}>Change Name</button>
</div>
);
}
請注意,當像這樣使用 Recoil 作為寫入快取時,由於更新選取器會在提交遠端突變前更新使用者介面,因此無需針對「樂觀回應」進行中繼的概念。若發生伺服器錯誤,區域更新將會回滾。
區域更新
commitLocalUpdate()
中繼 API 可用於 GraphQL 狀態的區域更新,而無需發出網路要求來更新伺服器。更新將導致訂閱受影響查詢和選取器的所有相關元件重新呈現。