简体   繁体   中英

ReactJS: Redux state is not changing

I'm just starting with React and Redux and stumbled upon something I can't figure out by myself - I think that Redux state is not changing and it's causing (some of) errors. I'm checking state with use of remote-redux-devtools@0.5.0. My code:

Categories.js:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { getCategories } from '../../actions/categories';

export class Categories extends Component {
    static propTypes  = {
        categories: PropTypes.array.isRequired
    };

    componentDidMount() {
        this.props.getCategories();
    }

    render() {
        return (
            <div>
                Placeholder for categories.
            </div>
        )
    }
}

const mapStateToProps = state => ({
    categories: state.categories.categories
});

export default connect(mapStateToProps, { getCategories })(Categories);

../../actions/categories.js:

import axios from "axios";

import { CATEGORIES_GET } from "./types";

export const getCategories = () => dispatch => {
  return axios
    .get("/api/notes/categories/")
    .then(res => {
      dispatch({
        type: CATEGORIES_GET,
        payload: res.data
      });
    })
    .catch(err => console.log(err));
};

reducers/categories.js:

import { CATEGORIES_GET } from '../actions/types.js';

const initialState = {
    categories: []
};

export default function (state = initialState, action) {
    switch (action.type) {
        case CATEGORIES_GET:
            return {
                ...state,
                categories: action.payload
            };
        default:
            return state;
    }
}

store.js:

import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'remote-redux-devtools';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const initialState = {};
const middleware = [thunk];

const store = createStore(
    rootReducer,
    initialState,
    composeWithDevTools(applyMiddleware(...middleware)));

export default store;

reducers/index.js

import { combineReducers } from "redux";
import categories from './categories';

export default combineReducers({
    categories,

});

Using remote-redux-devtools, I've never seen anything in my state. Currently this code above gives me 3 errors, two of them being

this.props.getCategories is not a function

My guess is that because there is some issue with Categories class, it's not passing anything to state and it could be root cause of errors. I had one more error, connected to Categories not being called with attributes, but for debug purposes I put empty array there - one error dissapeared, but that's it. I've also tried adding constructor to Categories and called super() , but did not help also.

I believe your issue is that you're exporting your Categories class twice, once connected, the other not.

If you remove export from export class Categories extends Component , does it work as expected?

When you're mapping the state in a component, you must access the desired variable through a reducer.

So instead of:

const mapStateToProps = state => ({
    categories: state.categories
});

You must use:

const mapStateToProps = state => ({
    categories: state.categories.categories
});

Your props don't have getCategories method, because you didn't pass it as a function to connect .

A better approach is to define only the action code in your actions file and then use mapDispatchToProps .

../../actions/categories.js

import axios from "axios";

export const getCategories = () => {
  axios
    .get("/api/notes/categories/")
    .then(res => res.data);
    })
    .catch(err => console.log(err));
};

Categories.js

import { getCategories } from '../../actions/categories'
import { CATEGORIES_GET } from "./types";

const mapDispatchToProps = dispatch => {
  return {
     getCategories: () => dispatch(() => { type: CATEGORIES_GET, payload: getCategories() }),
  }
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM