@airma/react-effect
@airma/react-effect
is designed for managing the asynchronous effect state for react components.
Why effects
Do asynchronous operations in effects
is more effective.
- You can pre-render a default result for asynchronous operation before it is really resolved.
- It makes component render with less asynchronous effects spread in event handle callbacks.
If you are ready to improve your react app codes with less asynchronous operation effects, please take minutes to read the documents of this tool.
Basic Usage
The basic hook API useQuery
and useMutation
maintains a promise result state. It contains promise information data
, error
and status isFetching
, isError
for a render help.
UseQuery
This API is often used to query data with a promise returning callback and parameters for this callback. When useQuery
is mounted, or the elements of parameters changed, it calls query callback.
import React from 'react';
import {useQuery} from '@airma/react-effect';
import {User} from './type';
type UserQuery = {
name: string;
username: string;
}
const fetchUsers = (query: UserQuery):Promise<User[]> =>
Promise.resolve([]);
const App = ()=>{
const [query, setQuery] = useState({name:'', username:''});
const [state, trigger, execute] = useQuery(
fetchUsers,
[query]
);
const {
data,
isFetching,
error,
isError,
loaded
} = state;
......
}
The hook API useQuery
returns a tuple [state, trigger, execute]
. Element state
contains informations about this query action. Element trigger
is a no parameter callback which returns a state
promise, it should be used just like a query trigger. Element execute
is a callback which accepts parameters, and returns a state
promise.
If you don't want the auto query action happens, when the parameters are changed or setted first time, you should set optional config manual
to stop it.
import React from 'react';
import {useQuery} from '@airma/react-effect';
import {User} from './type';
const fetchUsers = (query: UserQuery):Promise<User[]> =>
Promise.resolve([]);
const App = ()=>{
const [query, setQuery] = useState({name:'', username:''});
const [state, trigger] = useQuery(
fetchUsers,
{manual: true}
);
const {
data,
isFetching,
error,
isError,
loaded
} = state;
const handleClick = async ()=>{
const {
data,
isFetching,
error,
isError,
abandon,
loaded
} = await trigger();
}
......
}
We do not recommend using the result promise returned by a trigger
callback, and that's why we call it a trigger
.
UseMutation
It is often used to mutate data with a promise returning callback and its parameters. It is always triggered or executed manually.
import React from 'react';
import {useMutation} from '@airma/react-effect';
import {User} from './type';
const saveUser = (user: User): Promise<User> =>Promise.resolve(user);
const App = ()=>{
const [user, setUser] = useState({name:'', username:''});
const [state, trigger, execute] = useMutation(
saveUser,
[user]
);
const {
data,
isFetching,
error,
isError
loaded
} = state;
const handleClick = ()=>{
trigger();
}
......
}
It only works in manual
mode, so you don't have to worry about the auto mutation happening.
Use Strategy
Sometimes you want to control the running way about the promise callback.
For example, we often save data oncely, and then unmount component immediately after saving success to prevent a repeat saving mistake.
import React from 'react';
import {useMutation, Strategy} from '@airma/react-effect';
import {User} from './type';
const saveUser = (user:User):Promise<User> =>
Promise.resolve(user);
const App = ()=>{
const [user, setUser] = useState({name:'', username:''});
const [state, trigger] = useMutation(
saveUser,
{
variables: [user],
strategy: Strategy.once()
}
);
const handleClick = async ()=>{
trigger();
}
......
}
Share promise state changes
There are steps you need to do for sharing promise state changes.
- Create a
session key
for every promise callback. - Set
session keys
to SessionProvider
for creating session store. - Use
session key
to link a SessionProvider
store for promise state sharing.
import React, {memo} from 'react';
import {
SessionProvider,
createSessionKey,
useSession,
useQuery
} from '@airma/react-effect';
import {User} from './type';
const fetchLoginUser = (query:UserQuery):Promise<User>=>
Promise.resolve({...});
const loginUser = createSessionKey(fetchLoginUser);
const Child1 = memo(()=>{
const [ state ] = useQuery(loginUser,[]);
return ......;
});
const Child2 = memo(()=>{
const [ state ] = useSession(loginUser);
return ......;
});
const App = memo(()=>{
return (
<SessionProvider value={loginUser}>
<Child1/>
<Child2/>
</SessionProvider>
);
})
Summary
The common usages about @airma/react-effect
are listed above, if you want to know more about it, please take this document.