In RecoilJS
docs, there is an example how to handle asynchronous data queries, but it's only about get data.
Let say I have a simple state:
const accountState = atom({
key: "accountState",
default: {
id: "",
name: "",
}
});
And a component which is a register form:
const RegisterForm = () => {
return (
<form>
<input type="text" name="username" />
<button type="submit">Register</button>
</form>
)
}
The posted data is in FormData
. After successfully created new account, the server will send a response that contains id
and name
of the account.
{
"id": "abcdef123456",
"name": "example"
}
This response data will be set as a new state of accountState
.
How can I handle the process in RecoilJS
?
You can just handle with http request and set the response to the state.
const RegisterForm = () => {
const [account, setAccount] = useRecoilState(accountState);
const handleSubmit = async e => {
e.preventDefault();
const response = await fetch(url, {
method: 'POST',
body: data,
});
const responseJson = await response.json();
setAccount(responseJson);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" name="username" />
<button type="submit">Register</button>
</form>
);
}
Edit
To have a reusable approach, I will suggest to build custom hooks for frequent usage
const useRegister = () => {
const setAccount = useSetRecoilState(accountState);
const register = useCallback(async (username)=> {
const response = await fetch(url, {
method: 'POST',
body: { username },
});
const responseJson = await response.json();
setAccount(responseJson);
}, [setAccount]);
return register;
}
const RegisterForm = () => {
const register = useRegister();
const handleSubmit = async e => {
e.preventDefault();
await register(username);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" name="username" />
<button type="submit">Register</button>
</form>
);
}