![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
React Hooks (useContext) based and lightweight state manage library.
action
and no reducer
/dispatch
/effects
in Redux/dva), action
is just normal function which support async/await
state
inside action
and middleware
is mutatable for easy understanding(while immutatable inside components)pending
and error
status of async action and update to DOM in real time by custom hook if needed$ npm install hookstore
# or
$ yarn add hookstore
Please check out all examples in the examples folder.
// src/models/count.js
export default {
namespace: 'count',
state: {
count: 0,
},
actions: {
add(n) {
const { state } = this.ctx;
state.count += n;
},
async asyncAdd(n) {
const { state } = this.ctx;
await new Promise(resolve => {
setTimeout(resolve, 1000);
});
state.count += n;
},
addx(n) {
const { state, actions } = this.ctx;
state.count += n;
actions.asyncAdd(n);
// await actions.asyncAdd(n); // use async/await can access asyncAdd() response
},
},
}
// src/models/list.js
import { getActions } from 'hookstore'; // access actions from other model
export default {
namespace: 'list',
state: {
list: [],
},
actions: {
async addItems(len) {
const { state } = this.ctx;
const newList = await fetchList(len);
state.list = newList;
},
async addByCount() {
const { state, getState, actions } = this.ctx;
const count = getState('count', s => s.count);
if (count <= 0) return console.warn(`count ${count}!`);
const newList = await fetchList(count);
state.list = newList;
getActions('count').add(1); // call count action
},
},
};
import { Provider } from 'hookstore';
import countModel from './models/count';
import listModel from './models/list';
import Counter from './src/components/Counter';
import List from './src/components/List';
function Root() {
return (
<Provider models={[ countModel, listModel ]}>
<h2>Counter</h2>
<Counter />
<Counter />
<h2>List</h2>
<List />
</Provider>
);
}
ReactDOM.render(<Root />, document.getElementById('root'));
// src/components/Counter.js
import { useStore } from 'hookstore';
export default () => {
const [ count, actions ] = useStore('count', s => s.count);
return (
<div>
{Math.random()}
<div>
<div>Count: {count}</div>
<button onClick={() => actions.add(1)}>add 1</button>
<button onClick={() => actions.addx(1)}>add 1 and async add 1</button>
</div>
</div>
);
}
Listening the executing status of actions, such as pending
if pending or error
whenever if exception is thrown.
// src/components/List.js
import { useStore, useStatus } from 'hookstore';
export default () => {
const [ state, actions ] = useStore('list');
const { pending, error} = useStatus('list/addItems');
const addItems = () => {
if (pending) return console.log('pls wait....');
actions.addItems(5);
};
return (
<div>
{Math.random()}
<div>
{ pending && <div>loading...<div> }
{ error && <div>{error.message}<div> }
<div>List items: {state.list.join()}</div>
<button onClick={addItems}>async add 5 items</button>
</div>
</div>
);
};
<Provider models>
The Provider
has to be put in the parent component, and maybe Provider
as root component is recommended.
const Root = () => (
<Provider models={[ model1, model2 ]}>
...
</Provider>
);
ReactDOM.render(<Root />, document.getElementById('root'));
It simply returns the [state, actions]
tuple, the state
ref to the lastest state of model, and actions
is collection of methods which is the recommended way to modify the status safely.
const Component = () => {
const [ name, actions ] = useStore('foo', s => s.name);
// ...
};
useStatus
hook is usually used to get the execution status of asynchronous actions in real time, and all components used useStatus
hook will received the actions status update and then update to the DOM.
const Component = () => {
const { pending, error } = useStatus('foo/someAsyncAction');
// ...
}
getActions
returns all actions of some model, ractically it is safe to call actions outside React Components, you can call actions anyway such as passing as props to a child component which wrappered with React.memo
or React.useMemo
.
// models/foo.js
import { getActions } from 'hookstore';
export default {
namespace: 'foo',
actions: {
const barActions = getActions('bar'); // access actions from `bar` model
// ...
}
}
Appling koa-like middleware to all the action.
import { Provider, applyMiddlewares } from 'hookstore';
import errorMiddleware from 'hookstore-error';
import loggerMiddleware from 'hookstore-logger';
import countModel from './models/count';
import listModel from './models/list';
import Counter from './src/components/Counter';
import List from './src/components/List';
function Root() {
useLayoutEffect(() => {
// if (/localhost|\btest\b/.test(location.hostname)) {
applyMiddlewares([ errorMiddleware(), loggerMiddleware ]);
// }
}, []);
return (
<Provider models={[ countModel, listModel ]}>
<h2>Counter</h2>
<Counter />
<Counter />
<h2>List</h2>
<List />
</Provider>
);
}
ReactDOM.render(<Root />, document.getElementById('root'));
custom middleware:
// middlewares/errHandler.js
export default async (ctx, next) => {
try {
await next();
} catch(e) {
console.error(`${ctx.namespace}/${ctx.action}`, e);
}
}
// use middleware
import errHandler from 'errHandler';
function Root() {
applyMiddlewares([errHandler]);
return (
<Privider model={model}>
// ...
</Privider>
);
}
The examples folder contains working examples. You can run one of them with
$ cd examples/[folder] && npm start
then open http://localhost:3000 in your web browser.
MIT © chemdemo
FAQs
Hook based and lightweight centralized state management for React.
The npm package hookstore receives a total of 6 weekly downloads. As such, hookstore popularity was classified as not popular.
We found that hookstore demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.