最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I set the result of an API call as the default value for a Recoil atom? - Stack Overflow

programmeradmin3浏览0评论

I'm trying to set the default value for an atom in RecoilJS as the value of an asynchronous API call. I'm doing this so that when a certain React component renders it will have all of the current sets in the database without having to call useEffect(). Here's my code...

const sets = (async () => await setService.getAll())()

export const setsState = atom({
  key: 'sets',
  default: sets
})

Here's the error I'm getting...

index.js:1 Warning: Cannot update a component (`Batcher`) while rendering a different component (`App`). To locate the bad setState() call inside `App`, follow the stack trace as described in 
    in App (at src/index.js:10)
    in Router (created by BrowserRouter)
    in BrowserRouter (at src/index.js:9)
    in RecoilRoot (at src/index.js:8)

Is there something fundamentally wrong in the approach that I am taking? Should I be accomplishing this another way? Am I doing something wrong, or is this just a broken feature of Recoil?

I'm trying to set the default value for an atom in RecoilJS as the value of an asynchronous API call. I'm doing this so that when a certain React component renders it will have all of the current sets in the database without having to call useEffect(). Here's my code...

const sets = (async () => await setService.getAll())()

export const setsState = atom({
  key: 'sets',
  default: sets
})

Here's the error I'm getting...

index.js:1 Warning: Cannot update a component (`Batcher`) while rendering a different component (`App`). To locate the bad setState() call inside `App`, follow the stack trace as described in https://facebook.com/setstate-in-render
    in App (at src/index.js:10)
    in Router (created by BrowserRouter)
    in BrowserRouter (at src/index.js:9)
    in RecoilRoot (at src/index.js:8)

Is there something fundamentally wrong in the approach that I am taking? Should I be accomplishing this another way? Am I doing something wrong, or is this just a broken feature of Recoil?

Share Improve this question asked Aug 4, 2020 at 22:07 jackpalaiajackpalaia 811 silver badge5 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 17

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

const mySelector = selector({
  key: 'mySelector',
  get: async ({get}) => {
    return await setService.getAll()
  }
})

const myAtom = atom({
  key:'myAtom',
  default: mySelector
})

Here is a Typescript example, inspired by this answer.

// 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.

the warning you're reporting is known by the Recoil maintainers and it will be fixed in the next releases.

NOT SUGGESTED: If you want to hide it temporarily you could downgrade React to v16.12.0, it's up to you if you could live with this warning until the next Recoil release

发布评论

评论列表(0)

  1. 暂无评论