2017-04-05 68 views
1

我正在使用Recompose设置React Native中的用户登录屏幕,其中包含单独的动作和reducer文件,但我的reducer永远不会被调用。目前,还只是触发doUserLogin()重新合成处理登录按钮:React Native重构动作不触发reducer

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(),我的减速机从来没有被称为。但减速捡其他行动(从导航等) - 它根本不是从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; 

任何建议将不胜赞赏。

回答

1

好吧,看起来我能弄清楚这一点。简而言之,在loginScreen.js我需要添加mapStateToPropsmapDispatchToProps函数,它们被传递给connectwithHandlers然后dispatchloginUser()函数在我的动作文件中作为道具。

更新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

实际上,对于这个特殊的情况,你可以完全抛弃与帮手。

您只需将动作创建者传递给react-redux connect函数,以便将其绑定到调度函数,就像您所示。更多,请查看connect文档。您可以在连接的第三个参数中访问组件的道具,并进一步创建依赖道具的处理程序。

你的情况可能是这样的

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

注意我们是如何创造新的功能,这将作为一个新的道具组件,以类似的方式来withHandler帮手

+0

嗨,何塞。感谢你的回答!不确定你到底在说什么。你可以用一些代码来扩展答案吗? – GollyJer

+0

@GollyJer在代码中添加了一个小例子... –

相关问题