React redux对问题的分离

时间:2016-02-18 16:55:07

标签: asynchronous reactjs q redux redux-thunk

我正在尝试构建一个简单的应用来查看从美国国家航空航天局的日间服务图片(https://api.nasa.gov/api.html#apod)发布的照片​​。目前正在观看按键,然后根据按键是向左,向上,向右或向下的箭头来更改日期(和异步图片)。这些将相应地改变一周或一天所代表的日期(想象一次在一个正方形的日历上移动)。

我遇到的问题是:我创建了一个异步动作创建器来获取下一个潜在的日期 - 但是我需要知道应用程序的当前状态以及用于检索新日期的按键。有没有办法将其封装到动作创建者中?或者我应该将应用程序状态放在应用程序中调用导出的动作创建者的位置,这样我可以让我的动作创建者不知道应用程序的状态?我试图通过将componentDidMount中的keydown函数绑定到顶级Component来实现此目的,但是对应用程序存储的绑定似乎并不反映reducer中发生的更改。 / p>

异步逻辑依赖于redux-thunk中间件和q:

// This function needs to know the current state of the application
// I don't seem to be able to pass in a valid representation of the current state
function goGetAPIUrl(date) {
   ...
}

function getAsync(date) {
  return function (dispatch) {
    return goGetAPIUrl(date).then(
      val => dispatch(gotURL(val)),
      error => dispatch(apologize(error))
    );
  };
}

export default function eventuallyGetAsync(event, date) {
  if(event.which == 37...) {
    return getAsync(date);
  } else {
    return {
      type: "NOACTION"
    }
  }
}

这是与gridAppState的顶级绑定,以及在顶层发生的其他可能与我不太了解相关的内容。

class App extends React.Component {
  componentDidMount() {
    const { gridAppState, actions } = this.props;
    document.addEventListener("keydown", function() {
      actions.eventuallyGetAsync(event, gridAppState.date);
    });
  }
  render() {
    const { gridAppState, actions } = this.props;
    return (
        <GridApp gridAppState={gridAppState} actions={actions} />
    );
  }
}

App.propTypes = {
  actions: PropTypes.object.isRequired,
  gridAppState: PropTypes.object.isRequired
};

function mapStateToProps(state) {
  return {
    gridAppState: state.gridAppState
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(GridActions, dispatch)
  };
}

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

我已经验证了正确修改的日期对象是否已经到达reducer - 但是gridAppState似乎停留在我加载的初始日期。

在redux中处理依赖附加事件处理程序和当前应用程序状态的异步逻辑的正确方法是什么?有没有正确的方法来做这三个?

1 个答案:

答案 0 :(得分:2)

您应该处理组件中的事件,并根据按下的键调用正确的操作。

因此,当您发送异步操作时,您可以执行类似

的操作
export default function getNextPhoto(currentDate) {
  return (dispatch) => {
    const newDate = calculateNewDate(currentDate);

    dispatch(requestNewPhoto(newDate));

    return photosService.getPhotoOfDate(newDate)
    .then((response) => {
      dispatch(newPhotoReceived(response.photoURL);
    });
  };
}

您应该处理组件上的按键事件,并在您知道需要获取新照片时发送动作。

您的应用程序看起来像

class App extends React.Component {
  componentDidMount() {
    const { gridAppState, actions } = this.props;
    document.addEventListener("keydown", function() {
      if (event.which == 37) {
        actions.getNextPhoto(gridAppState.date);
      } else if (...) {
        actions.getPrevPhoto(gridAppState.date);
      }

      // etc
    });
  }
}

顺便说一句,你仍然错过了在Redux商店中更新状态的缩减器。