MonkeyBonkey MonkeyBonkey - 15 days ago 4
Javascript Question

How to get reference to the dispatch method from a component method in my react-native redux app

In my react-native app, I'm trying to wire up a login button using redux connect. When I try to trigger my handleLogin function, it looks like

this
in the handleLogin function is bound to the button, and not the component. What's the best way to structure this method. I could pass in the dispatch function as an argument to
handleLogin
but is there a cleaner way to get the dispatch reference from within the function?

class Profile extends Component {

handleLogin() {
// wrong `this`, this.props is null and this refers to the button, not the component
this.props.dispatch(login);
}

handleLogout() {
this.props.dispatch(logout);
}

render() {
const { dispatch, isAuthenticated, errorMessage, username } = this.props;
return (
<View style={styles.outer}>
{ isAuthenticated ? (
<Button style={{ backgroundColor: 'red' }} textStyle={{ fontSize: 18 }} onPress={() => dispatch(logout)} >
Logout {username}
</Button>
) : (
<Button style={{ backgroundColor: 'green' }} textStyle={{ fontSize: 18 }} onPress={this.handleLogin(dispatch)} >
Login
</Button>
)}
</View>
);
}

};


I'm assuming that my connect method automatically wires up dispatch to my components props.

Profile.propTypes = {
dispatch: PropTypes.func.isRequired,
username: PropTypes.string,
photo: PropTypes.string,
isAuthenticated: PropTypes.bool.isRequired,
errorMessage: PropTypes.string,
};

function mapStateToProps(state) {
const { user } = state;
const { isAuthenticated, errorMessage, photo, username } = user;
return {
username,
photo,
isAuthenticated,
errorMessage,
};
}

export default connect(mapStateToProps)(Profile);

Answer

You have options when trying to correct bind a method to an inline callback:

Also: You're assumption that omitting the mapDispatchToProps results in the dispatch being mapped to the props as this.props.dispatch is correct.


Use the arrow function:

onPress={this.handleLogin(dispatch)}

to:

onPress={() => handleLogin}

// this is lexcially bound inside an arrow function, yay!


Use bind in the constructor function:

constructor(props){
  super(props)

  this.handleLogin = this.handleLogin.bind(this);
}

Use bind within the inline callback:

onPress={this.handleLogin.bind(this);}