Post data through API with RecoilJS

Viewed 1515

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?

1 Answers

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>
  );
}
Related