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