Dan Rubio
Dan Rubio

Reputation: 4907

How can I connect my mapDispatchToProps to an onClick prop?

I'm having a bit of difficulty implementing redux in a simple react project that I'm creating. For clarification, it's a react 360 webvr project but I've seen many similarities with react native that I'm sure this can work.

The project that I'm trying to do is simply changing the background color of a component on the click of a button. Below is my code:

constants.js

export const PICK_COLOR = 'PICK_COLOR';

actions.js

import { PICK_COLOR } from './constants'

export const pickColor = (color) => ({
  type: PICK_COLOR,
  payload: color
})

reducers.js

import { PICK_COLOR } from './constants';

const initialColor = {
  backgroundColor: 'white'
}

export const chooseColor = (state = initialColor, action={}) => {
  switch (action.type) {
    case PICK_COLOR:
      return Object.assign({}, state, {backgroundColor: action.payload})
    default:
      return state
  }
}

index.js

import React from 'react';
import { createStore } from 'redux';
import { Provider, connect } from 'react-redux';
import { chooseColor } from './reducers';
import { pickColor } from './actions';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  VrButton
} from 'react-360';

const store = createStore(chooseColor);

const mapStateToProps = state => {
  return {
    backgroundColor: state.chooseColor.backgroundColor
  }
}

const mapDisptachToProps = (dispatch) => {
  return {
    onChooseColor: (event) => dispatch(pickColor(event.target.value))
  }
}

class App extends React.Component {
  render() {
    const { backgroundColor, onChooseColor } = this.props;
    return (
      <Provider store={store}>


         ###########################################
         I want this to change background color with 
         the click of a button.

        <View style={[styles.panel, backgroundColor: this.props.backgroundColor]}>
         ###########################################

          <VrButton style={styles.greetingBox} onClick={onChooseColor('blue')}>
            <Text style={[styles.greeting, {color: 'blue'}]}>
              Blue
            </Text>
          </VrButton>
        </View>
      </Provider>
    );
  }
};

const connectedApp = connect(mapStateToProps, mapDisptachToProps)(App);


AppRegistry.registerComponent('App', () => App);

The problem I'm having is getting over the finish line. I think I have everything set up almost correctly, but I'm unable to trigger any state change. The part where I'm getting confused is how do I connect my onClick prop handler to a state change and pass an argument? I've mixed and matched so many tutorials and videos that my head is spinning at the moment and I'm not entirely wrapping my head about setting up redux yet to troubleshoot effectively.

From what I've gathered, I don't think I have my mapDispatchToProps correctly because in the console I get the error that OnChooseColor is not a function. But how am I supposed to trigger the change? Can someone help pinpoint where I am going wrong? The help would be appreciated.

Upvotes: 0

Views: 164

Answers (2)

yiffyiffyiff
yiffyiffyiff

Reputation: 158

Could it be that in your mapStateToProps you are reading from state.chooseColor.backgroundColor, but it looks like your store has the shape state.backgroundColor (from what I can tell by the reducers.js)?

It's a bit late for me, so I'll probably have a look at this again tomorrow! (I'll try being more hands-on than just staring at the code!). But I'd definitively try to debug your store in your browser, by setting some breakpoints and having a look at what the store contains. There's also some handy browser extensions for react and redux that I would try out as well! (they should in theory make it easier to see what's going on with redux & react).

I can at least vouch for the react extension myself, I use it heavily just for the feature of being able to tell me which React component I'm looking at (as the DOM renders into <div> and not <MyComponent>!)

Edit: I made a small example that's very similar to this one here!

Upvotes: 1

RedPandaz
RedPandaz

Reputation: 6286

Two things I can spot by scanning your code. 1. backgroundColor is on the state in reducer.

const mapStateToProps = state => {
  return {
    backgroundColor: state.backgroundColor
  }
}

  1. The function for onClick should be passed instead of calling it.

 onClick={() => onChooseColor('blue')}

Upvotes: 0

Related Questions