React
How to integrate with React
Even though we are not using redux
, if you are familiar with
react-redux then this will be an identical
experience because starfx/react
has an identical API signature.
useDispatch
, useSelector
, and createSelector
are the bread and butter of
redux
's integration with react
all of which we use inside starfx
.
1import {
2 TypedUseSelectorHook,
3 useApi,
4 useSelector as useBaseSelector,
5} from "starfx/react";
6import { schema, WebState } from "./store.ts";
7import { fetchUsers } from "./api.ts";
8
9const useSelector: TypedUseSelectorHook<WebState> = useBaseSelector;
10
11function App() {
12 const users = useSelector(schema.users.selectTableAsList);
13 const api = useApi(fetchUsers());
14
15 return (
16 <div>
17 {users.map((u) => <div key={u.id}>{u.name}</div>)}
18 <div>
19 <button onClick={() => api.trigger()}>fetch users</button>
20 {api.isLoading ? <div>Loading ...</div> : null}
21 </div>
22 </div>
23 );
24}
Hooks #
useSelector
#
Query your store with this hook.
1import { useSelector } from "starfx";
2
3function App() {
4 const data = useSelector((state) => state.data);
5 return <div>{data}</div>;
6}
useDispatch
#
Call thunks and endpoints with this hook.
1import { useDispatch } from "starfx";
2
3function App() {
4 const dispatch = useDispatch();
5
6 return (
7 <button onClick={() => dipatch({ type: "action!" })}>
8 Click me!
9 </button>
10 );
11}
useLoader
#
Will accept an action creator or action and return the loader associated with it.
1import { useLoader } from "starfx/react";
2
3const log = thunks.create<string>("log");
4
5function App() {
6 // this will grab loader for any `log` thunks dispatched
7 // `action.payload.name`
8 const loaderAny = useLoader(log);
9 // this will grab loader a specific `log` thunk dispatched
10 // `action.payload.key`
11 const loader = useLoader(log("specific thunk"));
12}
useApi
#
Will take an action creator or action itself and fetch the associated loader and
create a trigger
function that you can call later in your react component.
This hook will not fetch the data for you because it does not know how to fetch data from your redux state.
1import { useApi } from 'starfx/react';
2
3import { api } from './api';
4
5const fetchUsers = api.get('/users', function*() {
6 // ...
7});
8
9const View = () => {
10 const { isLoading, trigger } = useApi(fetchUsers);
11 useEffect(() => {
12 trigger();
13 }, []);
14 return <div>{isLoading ? : 'Loading' : 'Done!'}</div>
15}
useQuery
#
Uses useApi and automatically calls useApi().trigger()
1import { useQuery } from 'starfx/react';
2
3import { api } from './api';
4
5const fetchUsers = api.get('/users', function*() {
6 // ...
7});
8
9const View = () => {
10 const { isLoading } = useQuery(fetchUsers);
11 return <div>{isLoading ? : 'Loading' : 'Done!'}</div>
12}
useCache
#
Uses useQuery and automatically selects the cached data associated with the action creator or action provided.
1import { useCache } from 'starfx/react';
2
3import { api } from './api';
4
5const fetchUsers = api.get('/users', api.cache());
6
7const View = () => {
8 const { isLoading, data } = useCache(fetchUsers());
9 return <div>{isLoading ? : 'Loading' : data.length}</div>
10}
useLoaderSuccess
#
Will activate the callback provided when the loader transitions from some state to success.
1import { useApi, useLoaderSuccess } from "starfx/react";
2
3import { api } from "./api";
4
5const createUser = api.post("/users", function* (ctx, next) {
6 // ...
7});
8
9const View = () => {
10 const { loader, trigger } = useApi(createUser);
11 const onSubmit = () => {
12 trigger({ name: "bob" });
13 };
14
15 useLoaderSuccess(loader, () => {
16 // success!
17 // Use this callback to navigate to another view
18 });
19
20 return <button onClick={onSubmit}>Create user!</button>;
21};