ค้นหาเว็บไซต์

reactjs - Recoil: ตั้งค่าค่าใน Atom หลังจากเรียกใช้งาน api call ใน Selector


ฉันต้องการตั้งค่าค่าในอะตอมหลังจากเรียก API ในตัวเลือกเพราะฉันต้องเพิ่มพารามิเตอร์เพื่อเรียก API

อะตอม

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

ฉันอยากได้ค่าการดาวน์โหลดโดยไม่ต้องมีพารามิเตอร์หลังจากเรียกใช้ downloadDataResultsState เช่น const downloadDataResults=useRecoilValue(downloadDataResultsState); แต่ฉันก็ไม่พบวิธีที่จะทำได้

มีวิธีใดในการทำเช่นนั้นไหม?

คำตอบ #1

ลองอันนี้:

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

คำตอบ #2

ฉันนำสิ่งนี้ไปใช้ในวิธีแบบแฮ็ก และนี่คือโค้ดของฉันโดยใช้รายการแท็กเป็นตัวอย่าง:

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

ฉันกำลังใช้ hooks สำหรับจัดการรายการแท็กและข้อมูลแท็ก:

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