1.0.8 • Published 2 years ago

rematch-model-extend v1.0.8

Weekly downloads
-
License
ISC
Repository
-
Last release
2 years ago

说明

rematch-model-extend主要为了拓展rematch和优化rematch使用体验

安装

npm i rematch-model-extend

优化1

集中收集model,webpack和vite都支持

import { init } from '@rematch/core'
import count from './count.js'
import test from './test.js'

const store = init({
    models: {
        count,
        test
    },
})

export default store

每次添加新的model时,都需要手动导入,是否可以通过配置自动导入?答案是可以的

webpack方式

解决:使用rematch-model-extend中的getAllModelsWebpack

  • 第一个参数requireContext(必填)支持单个或者数组的方式 -> 使用可以查询require.context
  • 第二个参数excludeFileArr(可选)排除某文件的自动收集
  • 收集model时,该方法会通过model中的name进行重名提示
import { init } from '@rematch/core'
+ import { getAllModelsWebpack } from 'rematch-model-extend'

const models = getAllModelsWebpack({
    requireContext: require.context('../../src', true, /.*\/model(\/.*)*\.js$/),
    excludeFileArr: ['./model/index.js']
})

const store = init({
    models: models,
})

export default store

vite方式

  • 使用rematch-model-extend中的getAllModelsVite

  • 第二个参数globEager(必填)支持单个或者数组形式

  • 第二个参数excludeFileArr(可选)排除某文件的自动收集
import { init } from '@rematch/core'
+ import { getAllModelsVite } from 'rematch-model-extend'

const models = getAllModelsVite({
    globEager: [
        import.meta.globEager('../../src/**/model/*.js'),
        import.meta.globEager('../../src/**/model.js'),
    ],
    excludeFileArr: ['../../src/model/index.js']
})
const store = init({
    models: models,
})

优化2

dispatch派发优化

注意:如果是纯ts开发,此优化可以忽略,此设计是为了js和ts混用时开发的

注意:即使effects是函数,其返回值也是可以推断出来的

dispatch({type: 'count/increment', payload: 1})

使用rematch的派发都会遇到这样的问题,需要我们手动拼接type和书写payload,这样写法及其不友好,且没有任何推断

我们可以根据model中reducers和effects推断出其中方法吗?答案是可以的

解决:使用rematch-model-extend中的createAction

model/count.js

+ import { createAction } from 'rematch-model-extend'

const count = {
    name: 'count',
    state: {
        count: 0,
    }, 
    reducers: {
        increment(state, payload) {
            state.count += payload
            return state
        },
    },
    effects: {
        async incrementAsync(payload, rootState) {
            await new Promise(resolve => setTimeout(resolve, 1000))
            this.increment(payload)
        },
    }
}

+ export const Actions = createAction(count)

export default count

app.js

Actions中就是自动推断出model/count模块中的reducers和effects中的方法

+ import { Actions } from './model/count'
+ dispatch(CountActions.increment(1)

优化3

model公共功能合并

注意:即使effects是函数形式,也是可以进行合并的

有这样一种场景:两个model中会有公共的部分,我们是否可以将这些公共的部分进行提取,实现共用?答案是可以的

举例:

model/count.js

import { createAction } from 'rematch-model-extend'

const count = {
    name: 'count',
    state: {
        count: 0,
        countRest: 'rest'
    }, 
    reducers: {
        increment(state, payload) {
            state.count += payload
            return state
        },
        handleCount() {
            ...
        }
    },
	...
}

export const Actions = createAction(count)
export default count

model/test.js

import { createAction } from 'rematch-model-extend'

const test = {
    name: 'test',
    state: {
        count: 0,
        testRest: 'rest'
    }, 
    reducers: {
        increment(state, payload) {
            state.count += payload
            return state
        },
        handleTest() {
            ...
        }
    },
	...
}

export const Actions = createAction(test)
export default test

我们发现count和test中有公共的部分

实现抽离如下:========================>

使用rematch-model-extend中的modelExtend

model/common.js

const common = {
    state: {
        count: 0
    },
    reducers: {
        increment(state, payload) {
            state.count += payload
            return state
        },
    },
}

export default common

model/count.js

import { modelExtend, createAction } from 'rematch-model-extend'
import common from './common'

const count = {
    name: 'count',
    state: {
       testRest: 'rest'
    }, 
    reducers: {
        handleCount() {
            ...
        }
    },
	...
}

const model = modelExtend(common, count)
export const Actions = createAction(model)
export default model

model/test.js

import { modelExtend, createAction } from 'rematch-model-extend'
import common from './common'

const test = {
    name: 'test',
    state: {
       testRest: 'rest'
    }, 
    reducers: {
        handleTest() {
            ...
        }
    },
	...
}

const model = modelExtend(common, test)
export const Actions = createAction(model)
export default model

其他

项目中可以自行考虑是否使用

rematch-model-extend其他方法:commonModelExtend方法

  • commonModelExtend中集合了特殊的reducers

  • 如:updateState更新简单类型

  • 如:updateDeepState更新复杂对象类型

  • 如:error更新state中的error属性

  • 如:updateParams更新state中的params属性

  • 感兴趣可以在源码中查找

使用如下

model/example.js

import { commonModelExtend, createAction } from 'rematch-model-extend'

const example = {
    name: 'example',
    state: {
        obj: {
            a: {
                b: '123'
            },
            arr: [1, 2, 3],
            arr1: [{ id: '1', text: 'name' }]
        },
        count: 0
    },
}

const model = commonModelExtend(example)

export const Actions = createAction(model)
export default model

app.js

import React from 'react'
import { connect } from 'react-redux'
import { Actions } from './model/example'

function App(props) {

  return (
    <div>
      <div>The exampleCount : {props.example.count}</div>
      <div>The exampleObj : {JSON.stringify(props.example.obj)} </div>
      <div>The exampleArr : {JSON.stringify(props.example.obj.arr)} </div>
      <div>The exampleArr : {JSON.stringify(props.example.obj.arr1)} </div>
      <div>
        <button onClick={() => props.dispatch(Actions.updateState({ count: 1 }))}>updateState</button>
        <button onClick={() => props.dispatch(Actions.updateDeepState({ 'obj.a.b': 456 }))}>updateDeepStateObj</button>
        <button onClick={() => props.dispatch(Actions.updateDeepState({ 'obj.arr.1': 5 }))}>updateArr</button>
        <button onClick={() => props.dispatch(Actions.updateDeepState({ 'obj.arr': null }))}>deleteArr</button>
        <button onClick={() => props.dispatch(Actions.updateDeepState({ 'obj.arr1.id_1.text': 'zs' }))}>updateDeepStateArr1</button>
        <button onClick={props.dispatch}>toCountIncrement</button>
      </div>
    </div>
  );
}

const mapState = state => ({
  example: state.example
})

export default connect(mapState)(App);
1.0.8

2 years ago

1.0.7

2 years ago

1.0.6

2 years ago

1.0.5

2 years ago

1.0.4

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago