首页 > 解决方案 > Redux - State is updating but React components are not

问题描述

Redux/ React-Redux isn't returning the state via mapStateToProps to the components despite the reducer correctly firing and assembling the correct state. I've followed the Redux code and the state seems to flow through, but flat out is not returned to the React component despite having wrapped it in the connect function.

Code excerpt below:

index.js (My app)

import { Provider, connect } from 'react-redux';
import { store } from './store/index';
import { fetchData, ghostFlag, dropDowned, addAttribute, setSelectedItem } from './actions/docActions';

    ...some code...

    render(){

      return(

        <span className = "app-container" id = {this.props.sidebar_shown}>

          <div className="sidebar" >

    <div className = "add_content_1"> 
                <h2 className="page-add-subheader">Content</h2>
                <TextAddContainer BlogSnapshot = {this.props.getSnapshot} CurrentEditPageHandle = {this.props.CurrentEditPageHandle} />
                <SidebarImageContainer CurrentEditPageHandle = {this.props.CurrentEditPageHandle}  />
              </div>



const mapStateToProps = (state, ownProps)  => {
  console.log("The state is:"+state);
  return state;
}

const mapDispatchToProps = dispatch => {
  return {
    fetchData: () => dispatch(fetchData (typeVar, snapshot)),

    updateHandle: () => dispatch(updateHandle(handle)),

  }
}

ReactDOM.render(
  <Provider store = {store}>
  <App />
  </Provider>,

    document.getElementById('root')
);

export default connect(mapStateToProps, mapDispatchToProps)(App);

Store :

import React from 'react';
import {applyMiddleware, createStore, combineReducers } from 'redux';
import {rootReducer} from '../reducers/reducers';

export const store = createStore(
    combineReducers({
        state: rootReducer
    }),
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);

import undoable, { distinctState } from 'redux-undo';

Reducers (confirmed working in devtools, but the returned state is NOT reaching my components!):

export const rootReducer = ( state , action) => {

    if(typeof(state) === "undefined"){
        state = 0;
    }

    switch (action.type){
        case 'SELECTED':
            return Object.assign({}, state, {

            })

        case 'DROPDOWN':
            return Object.assign({}, state, {

            })
        case 'PAGESNAP':
            if(action.payload){
                return Object.assign({}, state, {
                    PagesSnapshot : action.payload  
                })              
            }else { return state}

        case 'BLOGSNAP':
            if(action.payload){
                return Object.assign({}, state, {
                    BlogSnapshot : action.payload   
                })              
            }else { return state}
        case 'IMAGESNAP':
            if(action.payload){
                return Object.assign({}, state, {
                    ImageSnapshot : action.payload  
                })              
            }else { return state}
        case 'CURRENTEDITPAGE':
            return Object.assign( {}, state, {
                CurrentEditPageHandle : action.payload
            })

        default:
            return state
    }


}

As you can see I've mapped the connect function accordingly. What's going on?

标签: javascriptreactjsredux

解决方案


The main issue exists because you're referencing <App /> in the same file you're exporting it. At the time it's being rendered, you haven't actually connected your App to your store. You need <App /> to essentially be the connected version (export default connect(mapStateToProps, mapDispatchToProps)(App);).

The easiest way to remedy this, is to move the class to App.js and call it like below:

App.js:

class App {
    render() {
       ...
    }
}

const mapStateToProps = (state, ownProps)  => {
  console.log("The state is:"+state);
  return state;
}

const mapDispatchToProps = dispatch => {
  return {
    fetchData: () => dispatch(fetchData (typeVar, snapshot)),

    updateHandle: () => dispatch(updateHandle(handle)),

  }
}

export default connect(mapStateToProps, mapDispatchToProps)(App);

index.js:

import App from './app'
...Setup store...

ReactDOM.render(
 <Provider store = {store}>
    <App />
 </Provider>,

 document.getElementById('root')
);

推荐阅读