Search code examples
reactjsreduxcomponentsstate

React+Redux. Connect doesn't update state of component


I have some problem with Redux. I created Reduser and it work fine. It change store and i can show that in ReduxDevTools. But in the component state doesn`t update.

I have mapStateToProps, mapDispatchToProps, connect, and it all looks like in the documentation, but it doesn`t work.

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './css/index.css';
import App from './components/App.jsx';

import { createStore } from 'redux';
import { Provider } from 'react-redux';
import storeApp from './reducers';

let store = createStore(
    storeApp,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    );

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

it my reducer which I combine in combineReducers;

import {FIRST_ACTION, SECOND_ACTION ,THIRD_ACTION} from '../actions/actionTypes';

const firstRedus = (state = {}, action) => {

switch (action.type) {
    case FIRST_ACTION:
        return Object.assign({}, state, {
            test: action.text
        })
    case SECOND_ACTION:
        return Object.assign({}, state, {
            test: action.text
        })
    case THIRD_ACTION:
        return Object.assign({}, state, {
            test2: action.text
        })

    default:
        return state
 }
}
 export default firstRedus

This is my combineReducers

    import { combineReducers } from 'redux'
    import firstRedus from './firstRedus'


    export default combineReducers({
     firstRedus
    })

it my App.jsx component

    import React, { PureComponent } from 'react';
    import '../css/App.css';
    
    import { connect } from 'react-redux'
    import { bindActionCreators } from 'redux'
    import {actFirst,actSec} from '../actions/actions.js';
    
    class App extends PureComponent {
    
        constructor(props) {
            super(props)
            this.state = {
                test: this.props.test
            }
            this.handleClick1= this.handleClick1.bind(this);
            this.handleClick2= this.handleClick2.bind(this);
        }
        handleClick1(e){
            e.preventDefault();
            this.props.actFirst('first')
        }
        handleClick2(e){
            e.preventDefault();
            this.props.actSec('scond')
        }   
        render() {
          return (
            <div className="App">
            <ul>
                <li>{this.state.test}</li> //doesn't work
                <li>{this.props.test}</li>  //doesn't work
            </ul>               
                <button onClick={this.handleClick1}>test1</button>  
                <button onClick={this.handleClick2}>test2</button>  
            </div>
          );
        }
    }
    
    function mapStateToProps(state){
        return {
            test: state.test        
        }
    };
    function mapDispatchToProps(dispatch,ownProps) {
        return {
            actFirst: (text) => {
                dispatch(actFirst(text));
            },
            actSec: (text) => {
                dispatch(actSec(text));
            }       
        }
    };
    
    export default connect(
      mapStateToProps,
      mapDispatchToProps
    )(App);     

Solution

  • You can change like this

    import React, { PureComponent } from 'react';
    import '../css/App.css';
    
    import { connect } from 'react-redux'
    import { bindActionCreators } from 'redux'
    import {actFirst,actSec} from '../actions/actions.js';
    
    
    
    class App extends PureComponent {
    
        constructor(props) {
            super(props)
            this.state = {
                test: this.props.test
            }
            this.handleClick1= this.handleClick1.bind(this);
            this.handleClick2= this.handleClick2.bind(this);
        }
        handleClick1(e){
            e.preventDefault();
            this.props.dispatch(actFirst('first'))
        }
        handleClick2(e){
            e.preventDefault();
            this.props.dispatch(actSec('scond'))
        }   
        render() {
          return (
            <div className="App">
            <ul>
                <li>{this.state.test}</li> //doesn't work
                <li>{this.props.test}</li>  //doesn't work
            </ul>               
                <button onClick={this.handleClick1}>test1</button>  
                <button onClick={this.handleClick2}>test2</button>  
            </div>
          );
        }
    }
    
    function mapStateToProps(state){
        return {
            test: state.firstRedus.test        //change your state like this
        }
    };
    
    export default connect(mapStateToProps)(App);