1

我正在尝试构建一个简单的应用程序来查看从 nasa 的每日图片服务​​ ( https://api.nasa.gov/api.html#apod ) 发布的照片​​。当前正在监视按键,然后根据按键是向左、向上、向右或向下的箭头来更改日期(以及异步图片)。这些将相应地更改由一周或一天表示的日期(想象一次在日历上移动一个正方形)。

我遇到的问题是:我创建了一个异步操作创建器来获取下一个潜在日期 - 但是我需要知道应用程序的当前状态和按键来检索新日期。有没有办法将它封装到动作创建者中?或者我应该将应用程序状态放在应用程序中调用导出的动作创建者的位置,这样我就可以让我的动作创建者不知道应用程序的状态?我试图通过在componentDidMount顶层绑定 keydown 函数来做到这一点Component,但是绑定到应用程序商店似乎并没有反映减速器中发生的变化。

依赖 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);

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

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

4

1 回答 1

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);
    });
  };
}

您应该处理组件上的 keypress 事件,并在您知道需要获取新照片时调度您的操作。

你的应用看起来像

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 Store 中更新您的状态的 reducer。

于 2016-02-18T17:15:11.487 回答