Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6290

How do I separate api / async request logic from react components when using recoil

$
0
0

So at the moment I am having to put my request / api logic directly into my components because what I need to do a lot of the time is set state based on the response I get from the back end.

Below is a function that I have on my settings page that I use to save the settings to recoil after the user hits save on the form:

const setUserConfig = useSetRecoilState(userAtoms.userConfig);const submitSettings = async (values: UserConfigInterface) => {    try {        const { data: {data} } = await updateUser(values);        setUserConfig({            ...data        });    } catch (error) {        console.log('settings form error: ', error);    }}

This works perfectly...I just dont want the function in my component as most of my components are getting way bigger than they need to be.

I have tried making a separate file to do this but I can only use the recoil hooks (in this instance useSetRecoilState) inside of components and it just complains when I try and do this outside of a react component.

I have tried implementing this with recoils selector and selectorFamily functions but it gets kind of complicated. Here is how I have tried it inside of a file that has atoms / selectors only:

export const languageProgress = atom<LanguageProgress>({    key: "LanguageProgress",    default: {        level: 1,        xp: 0,        max_xp: 0    }})export const languageProgressUpdate = selectorFamily<LanguageProgress>({    key: "LanguageProgress",    get: () => async () => {        try {            const { data: { data } } = await getLanguageProgress();            return data;        } catch (error) {            console.log('get language progress error');        }    },    set: (params:object) => async ({set}) => {        try {            const { data: { data } } = await updateLanguageProgress(params);            set(languageProgress, {                level: data.level,                xp: data.xp,                max_xp: data.max_xp            });        } catch (error) {            console.log('language progress update error: ', error);        }    }});

What I want to do here is get the values I need from the back end and display it in the front which I can do in the selector function get but now I have 2 points of truth for this...my languageProgress atom will initially be incorrect as its not getting anything from the database so I have to use useGetRevoilValue on the languageProgressUpdate selector I have made but then when I want to update I am updating the atom and not the actual value.

I cannot find a good example anywhere that does what I am trying to here (very suprisingly as I would have thought it is quite a common way to do things...get data from back end and set it in state.) and I can't figure out a way to do it without doing it in the component (as in the first example). Ideally I would like something like the first example but outside of a component because that solution is super simple and works for me.


Viewing all articles
Browse latest Browse all 6290

Trending Articles