【问题标题】:React-Redux - How to redirect the page after storing the data in redux store?React-Redux - 如何在将数据存储在 redux 存储区后重定向页面?
【发布时间】:2021-04-15 18:44:53
【问题描述】:

我正在尝试一个 react-redux 示例代码,我想在单击“添加课程”时以一种形式添加课程,我想更新商店并重定向到包含课程列表的新页面。

但由于某种原因,重定向发生在调用 redux 操作创建者之后。它保持在同一页面中。

任何想法如何将结果重定向到不同的页面?

import React from "react";
import { connect } from "react-redux";
import * as courseActions from "../../redux/actions/courseActions";
import PropTypes from "prop-types";
import { bindActionCreators } from "redux";
import history from './history'


class CoursesPage extends React.Component {
  state = {
    course: {
      title: "",
    },
  };

  handleSubmit = (event) => {
    event.preventDefault();
    this.props.actions.loadCourses.createCourse(this.state.course).then(() => {
      alert('Inside Promise') 
      history.push('/AllCourses'); //This doesn't get executed.
  };

  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <h2>Courses</h2>
          <h3>Add Course</h3>
          <input type="submit" value="Add Course" />
          {this.props.courses.map((course) => (
            <div key={course.title}>{course.title}</div>
          ))}
        </form>
        <hr />
        
      </div>
    );
  }
}

CoursesPage.propTypes = {
  courses: PropTypes.array.isRequired,
  actions: PropTypes.object.isRequired,
};

function mapStateToProps(state) {
  return {
    courses: state.courses,
  };
}

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

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


Action Code:

import * as types from "./actionTypes";

export function createCourse(course) {
  return { type: types.CREATE_COURSE, course };
}


Reducer:

import * as types from "../actions/actionTypes";

export default function courseReducer(state = [], action) {
  debugger;
  switch (action.type) {
    case types.CREATE_COURSE:
      return [...state, { ...action.course }];
    default:
      return state;
  }
}

history.js

import createHistory from 'history/createHashHistory'

export default createHistory()

【问题讨论】:

  • 可以分享action code
  • 我刚刚更新了代码。谢谢
  • createCourse 不返回任何承诺
  • 你可以简单地做this.props.actions.loadCourses.createCourse(this.state.course); history.push('/allCourses');
  • 这个动作依赖于api调用,不需要等待响应,触发动作然后推送到新路由。删除then

标签: reactjs react-redux


【解决方案1】:

您可以创建一个自定义中间件来执行此操作:

const hasAddedData = (state) => {
    // Your checks    
}

const redirectMiddleware = history => storeAPI => next => action => {
    console.log('dispatching', action)
    const result = next(action);
    // If the action is the one you want to trigger the redirect (action.type)
    // and the state pass the checks (storeAPI.getState()),
    // do the redirect.
    //
    // This would be like:
    if (action.type === types.CREATE_COURSE && hasAddedData(storeAPI.getState())) {
        history.push(destinationPath);
    }
    // You must return the result of next(action) to avoid breaking Redux.
    return result;
}

无论您在哪里创建 Redux Store:

// history should already be provided by React Router.
const middlewareEnhancer = applyMiddleware(redirectMiddleware(history))

const store = createStore(yourRootReducer, middlewareEnhancer)

如果您还需要检查之前的状态,只需在运行 next(action) 之前使用 storeAPI.getState() 设置一个 const。您可以使用其他重定向检查或其他操作所需的场景来扩展您的中间件。

警告:我想为您提供原版代码解决方案,但请记住以下三点:

  • 这可能是由图书馆完成的更好和固执己见的任务(检查connected-react-router)。
  • 此外,您可以使用广泛接受的中间件库,例如 redux-saga,而不是为特定于操作的任务制作自定义中间件。
  • 考虑一下您的应用工作流程。您是否需要其他状态属性(完成标志、选择属性...)?是所有 CREATE_COURSE 动作都将重定向还是只重定向其中的一小部分?特定的 REDIRECT 操作会让您的事情变得更轻松吗?你真的需要一个命令式重定向,还是有可能,通过正确的状态结构,一个带有 React Router 组件的声明性重定向?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 2018-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-06
    • 1970-01-01
    相关资源
    最近更新 更多