首页 > 解决方案 > Connecting component to store

问题描述

I have a counter component, a app.js file and a reducer. But I can't connect to the store and I have some things no-undef

App.js

import { connect } from 'react-redux'
import Counter from './components/Counter';


// export default Counter;

function mapStateToProps(state) {
  return {
      countValue: state.count
  };
}

//Action

var increaseAction = { type:"increase" }
var decreaseAction = { type:"decrease" }

// Map Redux actions to component props.

function mapDispachToProps(dispach) {
  return {
      increaseCount: function() {
      return dispach(increaseAction);
      },
      decreaseCount: function() {
      return dispach(decreaseAction)
      }
  }
}

// The HOC aka Hight Order Componenets
var connectedComponent = connect (
  mapStateToProps,
  mapDispachToProps
)(Counter);

export default connectedComponent;

Then I have the counter.js

import React, { Component } from 'react';

class Counter extends Component {
    render() {
        return(
            <div className="container">
                <button onClick={this.props.decreaseCount}> - </button>
                <span> {this.props.countValue} </span>
                <button onClick={this.props.increaseCount}> + </button>
            </div>
        )
    }
}

export default Counter;

and finally actions.js file

import React, {Component} from 'react';
import Counter from './Counter';
import App from './App'

<Counter  increaseCount={increaseCount}
           decreaseCount={decreaseCount}
           countValue={countValue} 
                />

I also have index.js with

import React from 'react';
import ReactDOM from 'react-dom';
import {createStore} from 'redux';
import {Provider} from 'react-redux';
import reduceCounter from './reducer';
import './index.css';
import Actions from './components/Actions.js'
// import * as serviceWorker from './serviceWorker';

var store = createStore(reduceCounter);

ReactDOM.render(
    <Provider store={store}>
        <Actions> </Actions>
    </Provider>, document.getElementById("root"));

Failed to compile

./src/components/Actions.js
  Line 35:40:  'increaseCount' is not defined  no-undef
  Line 36:40:  'decreaseCount' is not defined  no-undef
  Line 37:37:  'countValue' is not defined     no-undef

I believe I need to wrap with redux connect, but I don't know how. Perhaps it will fic these errors.

reduce.js:

function counter(state, action) {
    if (state === undefined) {
        return { count: 0 };
    }

    var count = state.count;

    switch (action.type) {
        case "increase":
            return { count: count +1 }
        case "decrease":
            return { count: count -1 }
        default:
            return state;
    }
}

export default counter;

标签: reactjsreact-redux

解决方案


You are getting the following error message because the variables increaseCount, decreaseCount, and countValue are not defined in actions.js:

import React, { Component } from 'react';
import Counter from './Counter';
import App from './App';

export default () => (
    /**
     * The syntax someProp={someValue} translates to "I have a variable named 
     * someValue and I would like to set someProp equal to someValue." In your 
     * case, however, your variables that you are trying to pass as props, your 
     * someValues, are not defined.
     */
    <Counter
        increaseCount={increaseCount}
        decreaseCount={decreaseCount}
        countValue={countValue}
    />
);

You can solve the error and get your components to connect to the Redux store by:

  1. Removing Actions.js entirely
  2. Import your connected component from App.js
  3. Nest the connected component inside of <Provider>
import React from 'react';
import ReactDOM from 'react-dom';
import {createStore} from 'redux';
import {Provider} from 'react-redux';
import reduceCounter from './reducer';
import './index.css';
import Actions from './components/Actions.js' // Remove this
import ConnectedApp from 'path to App.js'; // Import App.js

// import * as serviceWorker from './serviceWorker';

var store = createStore(reduceCounter);

ReactDOM.render(
    <Provider store={store}>
        <ConnectedApp /> // Place your connected component here
    </Provider>, document.getElementById("root")
);

In response to: "I also need multiple and independent instances for counter component and data fetched from API"

I do not believe having one universal count variable for all independent Counter components is the right approach. You would need to create separate count variables for each individual Counter component. Along with that, you would most likely need a unique identifier, such as id, to associate your Counter components with their current count.

For data fetched from an API, you can use redux-thunk as middleware for your Redux store. This middleware extends the store's abilities to handle asynchronous actions.


推荐阅读