乐闻世界logo
搜索文章和话题

Recoil 如何将 http 请求结果设置为 atom 的默认值?

4 个月前提问
2 个月前修改
浏览次数40

3个答案

1
2
3

Recoil 是一个用于在React应用中管理状态的库。在Recoil中,atom是存储状态的基本单元,通常用于存储应用的一部分状态。你可以将HTTP请求的结果设置为atom的默认值,但通常并非直接将请求结果作为默认值,而是使用selector来处理异步逻辑,并将该selector与atom结合使用。

在Recoil中处理HTTP请求,并将结果设置为atom的默认值的一般步骤如下:

  1. 创建一个selector来执行HTTP请求。
  2. selectorget属性中执行异步函数,如使用fetch
  3. 创建一个atom,其默认值设置为这个selector

下面是一个如何实现这一流程的例子:

javascript
import { atom, selector, useRecoilValue } from 'recoil'; // 定义selector,用于执行HTTP请求 const fetchDataSelector = selector({ key: 'fetchData', // 唯一标识 get: async ({ get }) => { try { const response = await fetch('https://api.example.com/data'); const data = await response.json(); return data; // 返回请求的结果 } catch (error) { throw error; } } }); // 定义atom,其默认值是上面定义的selector const dataAtom = atom({ key: 'data', // 唯一标识 default: fetchDataSelector // 使用selector作为默认值 }); // 在组件中使用atom的值 const MyComponent = () => { // 使用useRecoilValue hook来读取atom的值 const data = useRecoilValue(dataAtom); // 渲染数据或加载状态 return ( <div> {data ? <div>{JSON.stringify(data)}</div> : <div>Loading...</div>} </div> ); };

在上面的代码中,fetchDataSelector负责执行HTTP请求,dataAtom则使用这个selector作为其默认值。在组件MyComponent中,我们使用了useRecoilValue hook来读取dataAtom的值,这时会触发fetchDataSelector的执行,并在请求完成后提供数据。

需要注意的是,当组件首次渲染时,Recoil会执行selector中的异步操作。如果数据请求成功,Recoil会更新atom的值为请求结果,这样任何使用该atom的组件都将重新渲染并显示新的结果。如果请求失败,你应该处理错误,例如,你可以设置错误状态并在UI中展示给用户。

2024年6月29日 12:07 回复

You can try creating a async selector and put into atom's default, like this:

shell
const mySelector = selector({ key: 'mySelector', get: async ({get}) => { return await setService.getAll() } }) const myAtom = atom({ key:'myAtom', default: mySelector })
2024年6月29日 12:07 回复

Here is a Typescript example, inspired by this answer.

shell
// Inside your React component const val = useRecoilValue(myAtom); const updateVal = useSetRecoilState(mySelector); // Update data with API call on form submit, and append new data to atom state const onFormSubmit: SubmitHandler<DataFormValues> = async (values) => { const createdData = await createDataWithApiCall(); await updateData([createdData]); }; // Inside recoil state file export const mySelector = selector({ key: 'mySelector', get: async (): Promise<Array<Data>> => { // Set default value to API result const apiData = await callApi(); return apiData; }, set: ({ set, get }, newData) => { // Update state w/ new appended values const currentState = get(myAtom); const newState = [...currentState, ...newData as Data[]]; set(myAtom, newState); }, }); export const myAtom = atom({ key: "myAtom", default: mySelector, });

Context: Don't be required to refetch entire to-do list from API each time a user adds an item to a to-do list. Call the API to add the new item, and append the new item to recoil state. Useful when user wants to make edits as well.

2024年6月29日 12:07 回复

你的答案