Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Redux mapDispatchToProps not receiving mapStateToProps

In my mapStateToProps function I set idToken and accessToken to values stored in state. This works, as I've been able to reference these values from the component. In mapDispatchToProps I try to use these props as arguments in my action. However, ownProps is an empty object. Why doesn't it have idToken and accessToken?

container:

import { connect } from 'react-redux'
import { toggleAddQuestionModal, fetchFriends } from '../actions'
import AddQuestionButtonComponent from '../components/AddQuestionButton'

const mapStateToProps = (state) => {
  auth = state.auth
  return {
    idToken: auth.token.idToken,
    accessToken: auth.profile.identities[0].accessToken,
  }
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    didPress: (idToken, accessToken) => {
      dispatch(toggleAddQuestionModal(true))
      dispatch(fetchFriends(ownProps.idToken, ownProps.accessToken))
    }
  }
}

AddQuestionButton = connect(
  mapStateToProps,
  mapDispatchToProps
)(AddQuestionButtonComponent)

export default AddQuestionButton

component:

'use strict';

import React, {
  Text,
  View,
  TouchableHighlight,
  PropTypes,
} from 'react-native'

import styles from './styles'

const AddQuestionButton = ({ didPress, idToken, accessToken }) => (
  <TouchableHighlight style={styles.actionButton} onPress={didPress(idToken, accessToken)}>
    <Text style={styles.actionButtonText}>+</Text>
  </TouchableHighlight>
)
AddQuestionButton.propTypes = {
  idToken: PropTypes.string.isRequired,
  accessToken: PropTypes.string.isRequired,
  didPress: PropTypes.func.isRequired,
}

export default AddQuestionButton

Why can't I access idToken and accessToken from ownProps? If this in an incorrect pattern, how should idToken and accessToken be accessed?

Thanks!

like image 222
Cole Avatar asked Apr 09 '16 19:04

Cole


People also ask

What is mapStateToProps and mapDispatchToProps in React Redux?

The mapStateToProps and mapDispatchToProps deals with your Redux store's state and dispatch , respectively. state and dispatch will be supplied to your mapStateToProps or mapDispatchToProps functions as the first argument.

Can mapDispatchToProps be null?

​ Yes. You can skip the first parameter by passing undefined or null . Your component will not subscribe to the store, and will still receive the dispatch props defined by mapDispatchToProps .

How often is mapStateToProps called?

As the first argument passed in to connect , mapStateToProps is used for selecting the part of the data from the store that the connected component needs. It's frequently referred to as just mapState for short. It is called every time the store state changes.

How do I access mapStateToProps in functional component?

You should connect the component to the store at first. The connection happen using the connect HOC provided by the react-redux package. The first paramter it takes, is a method that, given the global store, returns an object with only the properties you need in this component.


1 Answers

In mapStateToProps and mapDispatchToProps, the ownProps parameter refers to props the component receives via attributes, for example:

<AddQuestionButton isVisible={ true } />

The isVisible attribute will be passed as ownProps. In this way, you can have a component that receives some props from redux, and some props from attributes.

The connect method itself have a third parameter called mergeProps:

[mergeProps(stateProps, dispatchProps, ownProps): props] (Function): If specified, it is passed the result of mapStateToProps(), mapDispatchToProps(), and the parent props. The plain object you return from it will be passed as props to the wrapped component. You may specify this function to select a slice of the state based on props, or to bind action creators to a particular variable from props. If you omit it, Object.assign({}, ownProps, stateProps, dispatchProps) is used by default.

In the merge props, you actually get to combine all props together, as you can see in this answer by Dan Abramov to this issue:

function mapStateToProps(state, ownProps) {
  return {
    isFollowing: state.postsFollowing[ownProps.id]
  };
}

function mergeProps(stateProps, dispatchProps, ownProps) {
  const { isFollowing } = stateProps;
  const { dispatch } = dispatchProps;
  const { id } = ownProps;

  const toggle = isFollowing ?
    unfollowPostActionCreator :
    followPostActionCreator;

  return {
    ...stateProps,
    ...ownProps,
    toggleFollow: () => dispatch(toggle(id)))
  };
}

ToggleFollowButton = connect({
  mapStateToProps,
  null, // passing null instead of mapDispatchToProps will return an object with the dispatch method
  mergeProps
})(ToggleFollowButton)
like image 105
Ori Drori Avatar answered Sep 22 '22 10:09

Ori Drori