3

I want to set value in atom after calling API in selector because I have to add params to call API.

Atom

export const downloadData = atom({
  key: 'downloadData',
  default: [],
});

SelectorFamily

export const downloadDataResultsQuery = selectorFamily<Downloads[], string[]>({
  key: 'downloadDataResultsQuery',
  get:
    (names) =>
    ({ get }) => {
      const data = get(waitForAll(names.map((name) => downloadDataResultQuery(crateName))));

      // ATTENTION: I wanna set value for `downloadData` here

      return data;
    },
});

AtomFamily

export const downloadDataResultsState = atomFamily<Downloads[], string[]>({
  key: 'downloadDataResultsState',
  default: (crateNames) => downloadDataResultsQuery(names),
});

I wanna get the download value without the parameter after calling downloadDataResultsState like const downloadDataResults = useRecoilValue(downloadDataResultsState);, but I couldn't find ways to do it.

Are there any way to do that?

Pytan
  • 1,138
  • 11
  • 28

2 Answers2

1

Try this:

export const downloadDataResultsQuery = selector({
  key: 'key-value',
  get: () => {}, // optional
  set: ({ get, set }) => {
    const dataFromApi = ....()
    set(downloadData, dataFromApi); // this you need
  },
});
DoubleM
  • 123
  • 8
0

I implement this in a hack way and this is my code using a tag list for example:

// the tag atom
import { atomFamily, selectFamily } from 'recoil';

export const tagState = atomFamily( {
    key : 'tag',
    default : selectorFamily( {
        key : '#tag',
        get : id => async () => {
            return getTagDataByIdFromServer();
        }
    } )
} );


// the tag list
import { selectorFamily } from 'recoil';

export cost tagListState = selectorFamily( {
    key : 'tag/list',
    get( options ) {
        return async () => getTagList( options );
    }
} );

I am using hooks for managing tag list and tag data:

import { useState, useEffect } from 'react';
import { useRecoilValue, useRecoilCallback, useRecoilRefresher_UNSTABLE as useRecoilRefresher } from 'recoil';
import { tagState, tagListState } from '.....'

export function useTagList( options ) {

    const [ safe, setSafe ] = useState( false );
    const tags = useRecoilValue( tagListState( options ) );
    const refresh = useRecoilRefresher( tagListState( options ) );
    const save = useRecoilCallback( ( { set } ) => ( id, tag ) => {
        set( tagState( id ), tag );
    } );

    useEffect( () => {
        tags.forEach( tag => { save( tag.id, tag ) } );
        setSafe( true );
    }, [ tags ] )

    return { safe, tags, refresh };
}

LCB
  • 971
  • 9
  • 22