Cash rules everything around me, C.R.E.A.M., get the money, dollar dollar bill, y'all
NEAR Money Printer Go Brrr!
Print YUUUGE amounts of "NEAR CASH" bills and drop that STIMI!
Receivers can claim to an existing account or use funds to set up a brand new NEAR Account!
- Bundled with Parcel 2.0.1
- Minimal all-in-one state management with async/await support
The following steps are already done, but describe how to use
src/utils/state
to create and use your ownstore
andStateProvider
.
- Create a file e.g.
/state/app.js
and add the following code
import { State } from '../utils/state';
// example
const initialState = {
app: {
mounted: false
}
};
export const { store, Provider } = State(initialState);
- Now in your
index.js
wrap yourApp
component with theStateProvider
import { Provider } from './state/app';
ReactDOM.render(
<Provider>
<App />
</Provider>,
document.getElementById('root')
);
- Finally in
App.js
you canuseContext(store)
const { state, dispatch, update } = useContext(store);
<p>Hello {state.foo && state.foo.bar.hello}</p>
const handleClick = () => {
update('clicked', !state.clicked);
};
const onMount = () => {
dispatch(onAppMount('world'));
};
useEffect(onMount, []);
When a function is called using dispatch, it expects arguments passed in to the outer function and the inner function returned to be async with the following json args: { update, getState, dispatch }
Example of a call:
dispatch(onAppMount('world'));
All dispatched methods and update calls are async and can be awaited. It also doesn't matter what file/module the functions are in, since the json args provide all the context needed for updates to state.
For example:
import { helloWorld } from './hello';
export const onAppMount = (message) => async ({ update, getState, dispatch }) => {
update('app', { mounted: true });
update('clicked', false);
update('data', { mounted: true });
await update('', { data: { mounted: false } });
console.log('getState', getState());
update('foo.bar', { hello: true });
update('foo.bar', { hello: false, goodbye: true });
update('foo', { bar: { hello: true, goodbye: false } });
update('foo.bar.goodbye', true);
await new Promise((resolve) => setTimeout(() => {
console.log('getState', getState());
resolve();
}, 2000));
dispatch(helloWorld(message));
};
The default names the State
factory method returns are store
and Provider
. However, if you want multiple stores and provider contexts you can pass an additional prefix
argument to disambiguate.
export const { appStore, AppProvider } = State(initialState, 'app');
The updating of a single store, even several levels down, is quite quick. If you're worried about components re-rendering, use memo
:
import React, { memo } from 'react';
const HelloMessage = memo(({ message }) => {
console.log('rendered message');
return <p>Hello { message }</p>;
});
export default HelloMessage;
Higher up the component hierarchy you might have:
const App = () => {
const { state, dispatch, update } = useContext(appStore);
...
const handleClick = () => {
update('clicked', !state.clicked);
};
return (
<div className="root">
<HelloMessage message={state.foo && state.foo.bar.hello} />
<p>clicked: {JSON.stringify(state.clicked)}</p>
<button onClick={handleClick}>Click Me</button>
</div>
);
};
When the button is clicked, the component HelloMessage will not re-render, it's value has been memoized (cached). Using this method you can easily prevent performance intensive state updates in further down components until they are neccessary.
Reference: