Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

在一个module模块里,如何访问其它module模块的数据 #10

Closed
Running563 opened this issue Apr 10, 2020 · 2 comments
Closed

Comments

@Running563
Copy link

如下图所示 foo模块中的reducer如何访问到 bar模块中的 name 变量?

const bar= {
  state: {
       name:'bar'
  },
}
const foo = {
  state: { ... },
  reducer: {
    async changeNameCompose(name, moduleState, actionCtx) {
        //这里如何访问到 bar 模块中的 name变量?
    },
}

谢谢!

@fantasticsoul
Copy link
Contributor

fantasticsoul commented Apr 10, 2020

  • 方法1,使用顶层api getState(moduleName?:string)获得
import { getState } from 'concent';

export function someReducerFn(){
  const barState = getState('bar');//获得bar模块状态
}
  • 方法2,从actionCtx里直接获取, 推荐此方法
    可留意type文档IActionCtxBase 描述如下
export interface IActionCtxBase {
  callerModule: string;
  module: PropKey;
  committedStateMap: IAnyObj,
  committedState: IAnyObj,
  invoke: typeof refCtxInvoke;
  lazyInvoke: typeof refCtxInvoke;
  dispatch: typeof refCtxDispatch;
  lazyDispatch: typeof refCtxDispatch;
  rootState: IAnyObj;
  globalState: IAnyObj;
  moduleState: IAnyObj;
  moduleComputed: IAnyObj;
  setState: (obj: IAnyObj) => Promise<IAnyObj>;
  refCtx: IAnyObj;
}

从描述可看出rootState就是整个根状态,所以你在任意模块reducer方法的actionCtx里即可取到

import { getState } from 'concent';

export function someReducerFn(payload, moduleState, actionCtx){
  const barState = actionCtx.rootState.bar;//获得bar模块状态
}

bay the way,如果想在foo模块的reducer方法里调用bar模块的reducer方法去改变bar模块的状态有3种方法

  • 方法1,利用dispatch字符串匹配模式
// code in models/foo/reducer.js

// 同步调用
export async function someReducerFn(payload, moduleState, actionCtx){
  const ret = await actionCtx.dispatch('bar/someMethod', {val:'this is payload'});
}

// 异步调用
export function someReducerFn(payload, moduleState, actionCtx){
  actionCtx.dispatch('bar/someMethod', {val:'this is payload'});
}
  • 方法2,直接将对应方法引入过来
// code in models/foo/reducer.js
import * as barRd from 'models/bar/reducer';

// 同步调用
export async function someReducerFn(payload, moduleState, actionCtx){
  const ret = await actionCtx.dispatch(barRd.someMethod, {val:'this is payload'});
}

// 异步调用
export function someReducerFn(payload, moduleState, actionCtx){
  actionCtx.dispatch(barRd.someMethod, {val:'this is payload'});
}
  • 方法3,使用顶层reducer对象发起调用,run接口启动concent后,所有reducer方法都会收集到一个根Reducer对象上
// code in models/foo/reducer.js
import { reducer } from 'concent';

// 同步调用
export async function someReducerFn(payload, moduleState, actionCtx){
  const ret = await reducer.bar.someMethod({val:'this is payload');
}

// 异步调用
export function someReducerFn(payload, moduleState, actionCtx){
  reducer.bar.someMethod({val:'this is payload');
}

此种方法不推荐,因为会失去追踪源头调用处的能力(从哪个ui实例发起的调用),当然如果用户不在乎复盘源头调用处那么就无所谓了

此方法更适合在开发模式下,打开console,输入cc.reducer.***即可调用所有模块的各个reducer方法快速验证某些逻辑。

@fantasticsoul
Copy link
Contributor

已解决

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants