Replies: 6 comments 4 replies
-
I guess I can create a derived atom, and get the id from url by myself. const itemIdAtom = atom(() => {
// get id from url - can't call `useParams` - nested hooks
return id;
});
|
Beta Was this translation helpful? Give feedback.
-
Hi, thanks for opening a discussion. |
Beta Was this translation helpful? Give feedback.
-
I came up with this (this is the component that is attached to your export const currentEntityIdAtom = atom<string | null>(null)
export function MyRoute() {
const { id } = useParams()
const [entityId, setEntityId] = useAtom(currentEntityIdAtom)
useEffect(() => {
setEntityId(id)
return () => setEntityId(null)
}, [id]);
if (entityId !== id) return null
return <Component />
} |
Beta Was this translation helpful? Give feedback.
-
I think that
const OuterComponent: React.FC = () => {
const [searchParams] = useSearchParams();
const onWriteQs= useUpdateAtom(searchQsAtom);
const page = Number.parseInt(searchParams.get('page') ?? '1', 10);
const size = Number.parseInt(searchParams.get('size') ?? '10', 10);
useEffect(() => {
onWriteQs({ page, size });
}, [onWriteQs, page, size]);
return (
<React.Suspense fallback={<p>loading ...</p>}>
<InnerComponent />
</React.Suspense>
);
}
const InnerComponent: React.FC = () => {
const asyncFetchDataStore = useAtomValue(asyncFetchDataAtom);
return (
<div>{JSON.stringify(asyncFetchData)}</div>
);
}
// Atom definition
export const qsAtom = atom({ page: 1, size: 10 });
// code from #691
const baseFetchDataAtom = atom({ total: 0, items: [] });
const INIT = Symbol('for init');
export const asyncFetchDataAtom = atom(
(get) => get(baseFetchDataAtom),
(get, set, args) => {
if (args === INIT) {
const qs = get(qsAtom);
const url = new URL('https://pokeapi.co/api/v2/pokemon');
url.searchParams.set('offset', qs.page - 1 * qs.size);
url.searchParams.set('limit', qs.size);
fetch(url.href)
.then(res => set(baseFetchDataAtom, { total: res.data.count, items: res.data.results })
.catch() => set(baseFetchDataAtom, { total: 0, items: [] });
} else {
set(baseFetchDataAtom, args);
}
});
asyncFetchDataAtom .onMount = (dispatch) => {
dispatch(INIT);
}; Finally, I can use |
Beta Was this translation helpful? Give feedback.
-
If you are not using react-router or any other router libs, you could use jotai-location. |
Beta Was this translation helpful? Give feedback.
-
I just find it very easy with useHydrateAtoms. (yes, not for server side rendering) function Detail() {
const { itemId } = useParams();
useHydrateAtoms([[itemIdAtom, itemId]]);
const detailData = useAtom(detailAtom);
return <div>...detail data...</div>
} |
Beta Was this translation helpful? Give feedback.
-
Image a simple list-detail application like upon. and I want to use the async atom to store the detailed data.
this is my atom
my first temp is
<Provider initialValues={} />
, but it won't change the id after navigation.now I end up with
atomFamily
:another option in my mind is to set it manually
but I guess the async atom won't work as expect.
any other ideas? and what is the best practice?
Beta Was this translation helpful? Give feedback.
All reactions