modx is a lightweight library to help developer use redux in a simple way
npm install @olajs/modxModx is a lightweight library to help developer use redux in a simple way.
Just create a model, you can use it in global redux state,Class Component and Function Component , also easy to writeUnit Test for model with jest.
``shell script`
$ npm install @olajs/modx --save
$ yarn add @olajs/modx
- Create model
- Simple use
- Using in React with react-redux
- Using in Class Component
- Using in Function Component
- Using async logic
- useModel & withModel
- shareModel
`typescript
// modelA.ts
import { createModel } from '@olajs/modx';
export default createModel({
namespace: 'modelA',
state: {
counter: 0,
},
reducers: {
plus: (state) => ({ counter: state.counter + 1 }),
minus: (state) => ({ counter: state.counter - 1 }),
},
});
`
`typescript
// store.ts
import { createStore } from '@olajs/modx';
import modelA from './modelA';
const store = createStore({}, [modelA]);
const { namespace } = modelA;
console.log(store.getState()[namespace]);
// { counter: 0 }
store.dispatch({ type: ${namespace}/plus });
console.log(store.getState()[namespace]);
// { counter: 1 }
store.dispatch({ type: ${namespace}/plus });
console.log(store.getState()[namespace]);
// { counter: 2 }
store.dispatch({ type: ${namespace}/minus });`
console.log(store.getState()[namespace]);
// { counter: 1 }
`typescript jsx
// App.tsx
import React from 'react';
import { useGlobalModel } from '@olajs/modx';
import modelA from './modelA';
function App() {
const { state, dispatchers } = useGlobalModel(modelA);
return (
export default App;
`
`typescript jsx
// main.tsx
import React from 'react';
import ReactDom from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from '@olajs/modx';
import modelA from './modelA';
import App from './App';
const store = createStore({}, [modelA], { devTools: true });
ReactDom.render(
document.getElementByid('app'),
);
`
`typescript jsx
// withSingleModel.tsx
import React from 'react';
import { withSingleModel, UseModelResult } from '@olajs/modx';
import modelA from './modelA';
type Props = UseModelResult
class WithSingleModel extends React.PureComponent
render() {
const { state, dispatchers } = this.props.singleModel;
return (
export default withSingleModel(modelA)(WithSingleModel);
`
`typescript jsx
// useSingleModel.tsx
import React from 'react';
import { useSingleModel } from '@olajs/modx';
import modelA from './modelA';
function UseSingleModel() {
const { state, dispatchers } = useSingleModel(modelA);
return (
export default UseSingleModel;
`
`typescript jsx
// modelB.ts
import { createModel } from '@olajs/modx';
export default createModel({
namespace: 'modelB',
state: {
counter: 0,
},
reducers: {
plus: (state) => ({ counter: state.counter + 1 }),
minus: (state) => ({ counter: state.counter - 1 }),
},
effects: {
plusAsync(timeout: number) {
const { prevState } = this;
console.log(prevState); // { counter: xxx }
setTimeout(() => {
this.plus();
}, timeout);
},
minusAsync(timeout: number) {
const { prevState } = this;
console.log(prevState); // { counter: xxx }
setTimeout(() => {
this.minus();
}, timeout);
},
},
});
`
`typescript jsx
// useSingleModelB.tsx
import React from 'react';
import { useSingleModel } from '@olajs/modx';
import modelB from './modelB';
function useSingleModelB() {
const { state, dispatchers } = useSingleModel(modelB);
return (
export default useSingleModelB;
`
Simple way of useGlobalModel/withGlobalModel (global state) and useSingleModel/withSingleModel (component state) methods.
When use useModel hooks (since modx@2.1.2), modx will use model in global state first, if not exists, modx
will create a local state for it.
`typescript jsx
import React from 'react';
import { useModel } from '@olajs/modx';
import modelA from './modelA'; // global state
import modelB from './modelB'; // local state
function UseModelExample() {
const { state: stateA, dispatchers: dispatchersA } = useModel(modelA);
const { state: stateB, dispatchers: dispatchersB } = useModel(modelB);
return (
export default UseModelExample;
`
> since @olajs/modx@3.x
In some situation, more than one component will share some states which are not in global state.
Then you can use useShareModel/withShareModel,shareModel will create each modelConfig fileuseShareModel/withShareModel
per store. So use in different components with same modelConfig file
will get same store object, states and dispatchers of this store will be shared in these components.
For example:
- Comp1 and Comp2 share statesselector
- function used to prevent useless re-render
`typescript jsx
import React from 'react';
import { useShareModel } from '@olajs/modx';
import model from './modelA';
function Comp1() {
// only re-render when 'counter' changed
const selector = (state) => ({ counter: state.counter });
const { state } = useShareModel(model, selector);
return
function Comp2() {
// only re-render when 'counting' changed
const selector = (state) => ({ counting: state.counting });
const { state } = useShareModel(model, selector);
console.log('share Comp3 rendered');
return
> See /example directory to find more usage
Thanks
- Thanks dva for the
model` idea.