我可以将.getState()方法作为prop传递给我的组件吗?

时间:2016-04-20 03:42:20

标签: javascript frontend redux

我可以将调度作为支柱修补到我的容器。我也能够将状态对象的副本传递给我的容器。但是,我想要做的是传递方法," getState()"我的容器作为this.props.getState。

有没有办法做到这一点?

为什么我要这样做:

我的应用程序的结构相当大,为了简化,我试图阻止任何实际上不需要在单独文件中的容器内的逻辑("实用程序&# 34;文件夹)。例如,我们有一个自定义后端,所以处理从后端发送和接收的所有代码都存在于../utilities/api.js

现在,为了让这些实用程序可以访问商店,我一直在直接从../store/createStore.js导入商店。这样做很好,但我想要做的是使用依赖注入从调用api的组件传递dispatch和getState,因此为这些应用程序编写单元测试会更容易,并且使用我们将来可能开发的其他Redux应用程序来增加模块化。

基本上,我想写的是这样的:

//(Pesudocode)
// ../containers/SomeComponent.js
import api from '../utilities/api'

class SomeComponent extends Component {
  constructor(props){
    super(props);
    this.api = api(this.props.dispatch, this.props.getState);
}

someMethod(){
  this.api.foo('bar');
}
// etc. 

// pseudocode
// in ../utilities/api.js
export default function(dispatch, getState){
  return {
    foo: function (bar){
      // dispatch a complicated action which changes the state considerably
       dispatch(action.someAction(bar))
      // get the new state. 
       console.log("New State", getState());
    }
    baz: function (razz, dugi){
      // do something else
    }
  }

我发现,当该类构建时,可以发送当前状态的副本,但我真的需要 function getState()调用,因为其中一些函数是异步的。

可能还有其他模式,例如使用异步操作,但对于我们正在执行的操作,它可以正常运行。

2 个答案:

答案 0 :(得分:1)

这可以使用React的context来解决,它本质上是一个依赖注入机制,允许您在组件树中向任意级别发送类似prop的值。

如果你使用Redux或类似的状态容器,它的实现看起来像这样:

const store;

class App extends Component {

    static childContextTypes: {
        getState: React.PropTypes.func.isRequired
    }
    
    getChildContext() {
        return {
            getState: () => store.getState()
        }
    }

    render() {
        return <ChildComponent/>
    }
}

class ChildComponent extends Component {

    constructor(props, context) {
        super(props, context);
        this.api = api(props, context.getState);
    }
    
    static contextTypes: {
        getState: React.PropTypes.func.isRequired
    }
}

答案 1 :(得分:0)

您要做的是重新创建连接组件。 mapStateToProps调用中的connect()参数正在从您的商店中拉出选定状态并将其作为道具附加。我不推荐它,但你可以把整个州作为一个论点。

退一步看看你想要做什么,似乎你可以使用redux-thunk库并在你的api周围创建一个包装动作创建器,看起来像这样。

const apiAction = (url, onComplete) => {
    return (dispatch, getState) =>
        const state = getState();
        ...some logic

        api(foo, bar, onComplete)
}

当你应该使用redux动作创建器包装你的api调用时,你正在用你的api调用包装redux动作创建者。