【问题标题】:Trouble getting Redux Thunk to work无法让 Redux Thunk 正常工作
【发布时间】:2018-03-23 13:15:58
【问题描述】:

我正在学习 Redux,在尝试使用 redux-thunk 时遇到了问题。我正在将 Redux 用于我正在使用 this 构建的 Chrome 扩展。这是我目前的设置:

Index.js:

import {applyMiddleware,createStore} from 'redux';
import combineReducers from './reducers/index';
import {wrapStore} from 'react-chrome-redux';
import thunk from 'redux-thunk';

const middleware = applyMiddleware(thunk);
const store = createStore(combineReducers,{}, middleware);

store.subscribe(() => {
  console.log(store.getState().lastAction);
});

wrapStore(store, {
  portName: 'example'
});

reducers/index.js:

import {combineReducers} from 'redux';
import userAuthReducer from './userAuthReducer';
import manageTeamsReducer from './manageTeamsReducer';

function lastAction(state = null, action) {
  return action;
}

export default combineReducers({
  lastAction,userAuthReducer,manageTeamsReducer
});

ma​​nageTeamsReducer:

const initialState = {
  userTeams: []
};

const manageTeamsReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'SET_USER_TEAMS': {
      const newState = Object.assign(state, {
        userTeams:action.teams
      });
      return newState;
    }
    default:
      return state;
  }
}

export default manageTeamsReducer;

actions.js

export const getUserTeams = () => {

// if I uncomment the below block and make it a normal action then it works as desired
/*  return {
        type: "SET_USER_TEAMS",
        teams:[{_id:"asd",name:"fwewef"}]       
    }*/

//this action below is the thunk action that currently does not work
 return dispatch => {
      dispatch({
        type: "SET_USER_TEAMS",
                teams:[{_id:"asd",name:"fwewef"}]
      });
  };
};

组件:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import { bindActionCreators } from 'redux';
import * as authActions from '../../../../../../event/src/actions/userAuthActions';
import * as teamActions from '../../../../../../event/src/actions/manageTeams';

var cookies = require('browser-cookies');

class Login extends Component {

login(event) {
  this.props.actions.authActions.setUserLoggedInState(true)
  this.props.actions.teamActions.getUserTeams()     
}

  render() {
    return (
      <div className="login-par">
                <div onClick={this.login.bind(this)}></div>             
      </div>
    );
  }
}

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

const mapDispatchToProps = (dispatch) => {
  return {
        actions:{
            authActions: bindActionCreators(authActions,dispatch),
            teamActions: bindActionCreators(teamActions,dispatch)
    }}
};

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

应该发生的是当this.login 函数在组件中被点击时触发它应该触发这两个动作。第一个动作:this.props.actions.authActions.setUserLoggedInState(true) 触发没有问题,并且完全按照它应该做的。这是因为它是一个常规的 Redux 操作,它简单地返回一个带有类型和有效负载的对象。

然而,第二个动作需要是一个 Thunk,无论我如何用我在网上找到的示例重新安排我的代码,我似乎都无法让它工作。如果我取消注释 actions.js 中的第一个 return 语句并注释掉第二个 return 语句从而使其成为常规操作,那么它可以正常工作,但我需要能够使用 Thunk。

不确定是否有人能发现我是否设置了 Redux-Thunk 错误或其他任何问题?

注意:由于我正在使用 react-chrome-redux 包,有可能有不同的实现方式,但我看到有人使用相同的包,如 here 并在安装他们的包时看来他们已经设法让它正常工作了 - 但是我不明白为什么我的不能工作。

编辑

我按照 Sidney 的建议实现了别名如下:

Index.js:

import {applyMiddleware,createStore} from 'redux';
import combineReducers from './reducers/index';
import {wrapStore,alias} from 'react-chrome-redux';
import thunk from 'redux-thunk';
import aliases from './aliases/aliases';

const middlewares = applyMiddleware([alias(aliases), thunk]);
const store = createStore(combineReducers,{}, middlewares);

store.subscribe(() => {
  console.log(store.getState().lastAction);
});

wrapStore(store, {
  portName: 'example'
});

Aliases.js

const getUserTeams = (orginalAction) => {
  return (dispatch, getState) => {
      dispatch({
        type: "SET_USER_TEAMS_RESOLVED",
                teams:[{_id:"asd",name:"it worked!"}]   
      });
  };
};

export default {
  'SET_USER_TEAMS': getUserTeams // the action to proxy and the new action to call
};

actions.js

export const getUserTeams = () => {
    return {
        type: "SET_USER_TEAMS",
        teams:[]        
    }
};

reducer.js

const initialState = {
  userTeams: []
};

const manageTeamsReducer = (state = initialState, action) => {
    console.log(action)
  switch (action.type) {
    case 'SET_USER_TEAMS_RESOLVED': {
      const newState = Object.assign(state, {
        userTeams:action.teams
      });
      return newState;
    }
    default:
      return state;
  }
}

export default manageTeamsReducer;

组件

组件中没有任何变化,因为我的理解是我仍然应该发送相同的操作:

this.props.actions.teamActions.getUserTeams()

它仍然没有用“它有效!”返回给我的新对象。作为应用程序中的有效负载。我已尽力遵循示例和文档。不确定我是否错过了什么?

【问题讨论】:

    标签: javascript redux react-redux redux-thunk


    【解决方案1】:

    您需要使用 alias,它由 react-chrome-redux 库提供。

    您现在遇到的问题是异步操作返回一个函数,该函数无法通过消息传递协议发送到后台页面。相反,您将调度一个普通的对象动作,它在别名中定义为 thunk。

    The boilerplate repo that you linked 有一个如何设置和使用别名的示例。

    【讨论】:

    • 感谢您的推荐,我已经更新了我的代码以包含别名(上图),但仍然无法让它劫持原始操作...
    • 在您的组件文件中,单击内部
      应该会触发别名。也许确实如此,但我没有看到您从该州渲染 userTeams 的任何地方。
    • 我已经简化了在此处发布的组件,但如果成功,该组件将映射到 userTeams 数组。我还看到 SET_USER_TEAMS 动作被触发,而不是 SET_USER_TEAMS_RESOLVED(在控制台中),这告诉我它没有正确劫持它
    • 你的代码在公共仓库中吗?如果可能,请发布链接。我需要查看您的完整代码才能提供更多帮助。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签