React Native Recompose操作不会触发reducer

时间:2017-04-05 21:56:40

标签: reactjs react-native redux react-redux recompose

我正在使用Recompose在React Native中设置用户登录屏幕,使用单独的操作和reducer文件,但我的reducer永远不会被调用。目前,只有一个触发doUserLogin()重组处理程序的登录按钮:

loginScreen.js

import React from 'react';
import { Button, Text, View } from 'react-native';
import { connect } from 'react-redux';
import { withHandlers, compose } from 'recompose';
import { loginUser } from './user/userActions';

const LoginScreen = ({ user, doUserLogin }) => {
  return (
    <View style={styles.loginContainer}>
      {user ? <Text>Hi, {user.name}!</Text> : <Text>NOT Logged in!</Text>}
      <Button title="Log In" onPress={doUserLogin} />
    </View>
  );
};

export default compose(
  connect((state, props) => ({
    ...state.user,
  })),
  withHandlers({
    doUserLogin: props =>
      (event) => {
        console.log('LOGIN USER IN HANDLER'); // <-- THIS IS WORKING
        loginUser();
      },
  }),
)(LoginScreen);

doUserLogin()处理程序依次调用我的操作文件中的loginUser()

userActions.js:

import { LOGIN_REQUEST } from './actionTypes';

export const loginUser = () => {
  return (dispatch) => {
    console.log('In action'); // <-- THIS IS WORKING
    dispatch({ type: LOGIN_REQUEST });
  };
};

到目前为止,这么好。但是,当我dispatch()时,我的减速器永远不会被调用。但是reducer 正在采取其他行动(来自导航等) - 它根本就没有从上面的loginUser()接收行动:

userReducer.js:

import { LOGIN_REQUEST } from './actionTypes';

const userReducer = (state = initialState, action) => {
  console.log('In reducer'); <-- ** THIS IS NEVER CALLED **

  switch (action.type) {
    case LOGIN_REQUEST:
      return Object.assign({}, state, {
        isFetching: true,
      });
    case LOGOUT:
      return initialState;
    default:
      return state;
  }
};
export default userReducer;

任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:1)

好的,看起来我能够弄清楚这一点。简而言之,在loginScreen.js我需要添加mapStateToPropsmapDispatchToProps函数,这些函数会传递给connectwithHandlers然后可以dispatch我的操作文件中的loginUser()函数作为道具。

更新 loginScreen.js

import React from 'react';
import { Button, Text, View } from 'react-native';
import { connect } from 'react-redux';
import { withHandlers, compose } from 'recompose';
import { loginUser } from './user/userActions';

const LoginScreen = ({ user, doUserLogin }) => {
  return (
    <View style={styles.loginContainer}>
      {user ? <Text>Hi, {user.name}!</Text> : <Text>NOT Logged in!</Text>}
      <Button title="Log In" onPress={doUserLogin} />
    </View>
  );
};

const mapStateToProps = state => ({
  ...state.user,
});

const mapDispatchToProps = dispatch => ({
  loginUser: () => {
    dispatch(loginUser());
  },
});

export default compose(
  connect(mapStateToProps, mapDispatchToProps),
  withHandlers({
    doUserLogin: props =>
      () => {
        console.log('LOGIN USER IN HANDLER');
        props.loginUser();
      },
  }),
)(LoginScreen);

任何其他意见/建议仍然会受到赞赏。

答案 1 :(得分:1)

实际上,对于这种特殊情况,您可以完全解除withHandlers helper。

您只需将动作创建者传递给react-redux连接函数,以便将其绑定到调度函数,就像您所示。更重要的是,请查看TokenResponseException: 401 Unauthorized Exception when trying to access Admin SDK Google API文档。您可以在connect的第3个参数中访问组件的props,并进一步创建依赖于props的处理程序。

在你的情况下,它可能是这样的

    const mergeProps = (stateProps, dispatchProps, ownProps) => {
        return Object.assign({}, ownProps, stateProps, dispatchProps, {
          doUserLogin: () => {
            console.log('LOGIN USER IN HANDLER');
            console.log('accessing a prop from the component', ownProps.user);
            dispatchProps.loginUser();
          }
        });
      }
        export default connect(mapStateToProps,
                               mapDispatchToProps,
                               mergeProps)(LoginScreen);

请注意我们如何创建新函数,这些函数将作为组件的新prop使用,与withHandler helper类似