假设我有以下内容:

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return {
    type: SOME_ACTION,
  }
}

在那个动作创建器中,我想访问全局存储状态(所有还原器)。这样做更好吗:

import store from '../store';

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return {
    type: SOME_ACTION,
    items: store.getState().otherReducer.items,
  }
}

或:

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return (dispatch, getState) => {
    const {items} = getState().otherReducer;

    dispatch(anotherAction(items));
  }
}

当前回答

我想指出的是,从存储中读取数据并没有那么糟糕——根据存储决定应该做什么,可能比将所有内容都传递给组件然后作为函数的参数要方便得多。我完全同意Dan的观点,最好不要将store单独使用,除非你100%确定只用于客户端渲染(否则很难跟踪可能出现的bug)。

我最近创建了一个库来处理redux的冗长,我认为把所有东西都放在中间件中是一个好主意,这样你就可以把所有东西都作为依赖注入。

你的例子是这样的:

import { createSyncTile } from 'redux-tiles';

const someTile = createSyncTile({
  type: ['some', 'tile'],
  fn: ({ params, selectors, getState }) => {
    return {
      data: params.data,
      items: selectors.another.tile(getState())
    };
  },
});

然而,正如您所看到的,我们在这里并没有真正修改数据,所以很有可能我们可以在其他地方使用这个选择器来组合其他地方的数据。

其他回答

我同意@Bloomca。将存储所需的值作为参数传递给分派函数似乎比导出存储简单。我举个例子:

import React from "react";
import {connect} from "react-redux";
import * as actions from '../actions';

class App extends React.Component {

  handleClick(){
    const data = this.props.someStateObject.data;
    this.props.someDispatchFunction(data);
  }

  render(){
    return (
      <div>       
      <div onClick={ this.handleClick.bind(this)}>Click Me!</div>      
      </div>
    );
  }
}


const mapStateToProps = (state) => {
  return { someStateObject: state.someStateObject };
};

const mapDispatchToProps = (dispatch) => {
  return {
    someDispatchFunction:(data) => { dispatch(actions.someDispatchFunction(data))},

  };
}


export default connect(mapStateToProps, mapDispatchToProps)(App);

提出解决这个问题的另一种方法。这可能比Dan的解决方案更好,也可能更差,这取决于您的应用程序。

您可以通过将操作拆分为2个单独的函数来将状态从约简到操作中:第一个请求数据,第二个操作数据。你可以通过使用还原循环来做到这一点。

首先“请提供数据”

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
    return {
        type: SOME_ACTION,
    }
}

在减速机中,利用还原回路拦截请求并将数据提供给第二级动作。

import { loop, Cmd } from 'redux-loop';
const initialState = { data: '' }
export default (state=initialState, action) => {
    switch(action.type) {
        case SOME_ACTION: {
            return loop(state, Cmd.action(anotherAction(state.data))
        }
    }
}

有了数据,就可以做最初想做的事情了

export const ANOTHER_ACTION = 'ANOTHER_ACTION';
export function anotherAction(data) {
    return {
        type: ANOTHER_ACTION,
        payload: data,
    }
}

希望这能帮助到一些人。

我知道我来这里有点晚了,但我来这里是为了表达我对在行动中使用状态的渴望,然后形成了我自己的想法,当我意识到什么是我认为正确的行为时。

这就是选择器对我最有意义的地方。发出此请求的组件应该被告知是否该通过选择发出该请求。

export const SOME_ACTION = 'SOME_ACTION';
export function someAction(items) {
  return (dispatch) => {
    dispatch(anotherAction(items));
  }
}

这可能感觉像是泄露了抽象,但是您的组件显然需要发送消息,并且消息有效负载应该包含相关的状态。不幸的是,你的问题没有一个具体的例子,因为我们可以通过一个“更好的模型”的选择器和动作。

我想指出的是,从存储中读取数据并没有那么糟糕——根据存储决定应该做什么,可能比将所有内容都传递给组件然后作为函数的参数要方便得多。我完全同意Dan的观点,最好不要将store单独使用,除非你100%确定只用于客户端渲染(否则很难跟踪可能出现的bug)。

我最近创建了一个库来处理redux的冗长,我认为把所有东西都放在中间件中是一个好主意,这样你就可以把所有东西都作为依赖注入。

你的例子是这样的:

import { createSyncTile } from 'redux-tiles';

const someTile = createSyncTile({
  type: ['some', 'tile'],
  fn: ({ params, selectors, getState }) => {
    return {
      data: params.data,
      items: selectors.another.tile(getState())
    };
  },
});

然而,正如您所看到的,我们在这里并没有真正修改数据,所以很有可能我们可以在其他地方使用这个选择器来组合其他地方的数据。

我想建议另一个我认为最干净的替代方案,但它需要react-redux或类似的东西-同时我还使用了其他一些奇特的功能:

// actions.js
export const someAction = (items) => ({
    type: 'SOME_ACTION',
    payload: {items},
});
// Component.jsx
import {connect} from "react-redux";

const Component = ({boundSomeAction}) => (<div
    onClick={boundSomeAction}
/>);

const mapState = ({otherReducer: {items}}) => ({
    items,
});

const mapDispatch = (dispatch) => bindActionCreators({
    someAction,
}, dispatch);

const mergeProps = (mappedState, mappedDispatches) => {
    // you can only use what gets returned here, so you dont have access to `items` and 
    // `someAction` anymore
    return {
        boundSomeAction: () => mappedDispatches.someAction(mappedState.items),
    }
});

export const ConnectedComponent = connect(mapState, mapDispatch, mergeProps)(Component);
// (with  other mapped state or dispatches) Component.jsx
import {connect} from "react-redux";

const Component = ({boundSomeAction, otherAction, otherMappedState}) => (<div
    onClick={boundSomeAction}
    onSomeOtherEvent={otherAction}
>
    {JSON.stringify(otherMappedState)}
</div>);

const mapState = ({otherReducer: {items}, otherMappedState}) => ({
    items,
    otherMappedState,
});

const mapDispatch = (dispatch) => bindActionCreators({
    someAction,
    otherAction,
}, dispatch);

const mergeProps = (mappedState, mappedDispatches) => {
    const {items, ...remainingMappedState} = mappedState;
    const {someAction, ...remainingMappedDispatch} = mappedDispatch;
    // you can only use what gets returned here, so you dont have access to `items` and 
    // `someAction` anymore
    return {
        boundSomeAction: () => someAction(items),
        ...remainingMappedState,
        ...remainingMappedDispatch,
    }
});

export const ConnectedComponent = connect(mapState, mapDispatch, mergeProps)(Component);

如果你想重用它,你必须将特定的mapState、mapDispatch和mergeProps提取到函数中,以便在其他地方重用,但这使得依赖关系非常清楚。