Cannot get data out from redux store

Viewed 50

I can see all the data I want in the redux state from the website extensions, however, when I want to pull it out to use it in my component it said this.props.rules is undefined:

Here is the create-store.js:

import {createStore, applyMiddleware} from 'redux';
import mainReducer from './reducers/main-reducer';
import {composeWithDevTools} from 'redux-devtools-extension';
import thunk from 'redux-thunk';

export default () => {
  return createStore(mainReducer, composeWithDevTools(
    applyMiddleware(thunk)
  ))
}

Here is the mainReducer.js

import {combineReducers} from 'redux';

import rules from './rules-reducer';

export default combineReducers({
  rules
});

Here is the rules reducer:

const initialState = {
  allRules: [],
  singleRule: {}
}

export default (state = {}, {type, payload}) => {
  switch(type){
    case 'GET_RULES':
      console.log('got in get_rules reducer');
      return {
        ...state,
        allRules: payload
      }
    default:
      return state;
      }

};

Here is the getRulesAction:

export const getRulesAction = () => dispatch => {
  console.log('got into getrulesaction');
  const sheets = Object.entries(document.styleSheets);
  let allRules = [];
  for(let i = 0; i < sheets.length; i++){
    const sheet = sheets[i][1];
    const rules = Object.entries(sheet.cssRules);
    for(let j = 0; j < rules.length; j++){
      // console.log(rules[j][1].cssText);
      allRules.push(rules[j][1].cssText);
    }  
  }
  dispatch({
    type: 'GET_RULES',
    payload: allRules
  })
  
};

Here is the component I want to show my data:

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

class Rules extends Component {
  componentWillMount() {
    this.props.getRulesAction();
    console.log('props from will mount', this.props);
  }

  render(){
    console.log(this.props.rules);
    const fetchedRules = this.props.rules.map((rule,i) => {
        return <li key={i}>{rule}</li>
    }
    )

    return(
      <div>
        <h2>Component to get rules from the redux store</h2>
        {fetchedRules}
      </div>
    );
  }

}

Rules.propTypes = {
  getRulesAction: PropTypes.func.isRequired,
  rules: PropTypes.array.isRequired,
}

const mapStateToProps = state => ({
  rules: state.rules.allRules
})

export default connect(mapStateToProps, {getRulesAction})(Rules);

enter image description here

1 Answers

The error is most probably due to the following. When you declare a state, you need to initialize the state props. You do this by passing a default state to the reducer when it runs for the first time. However, your default state is set to en empty object:

export default (state = {}, {type, payload})

Therefore, when the component renders for the first time, this.props.rules is undefined. To remedy this, you'd want to initialize the state with initialState, which would ensure that this.props.rules is an array instead.

export default (state = initilState, {type, payload})

Later, when the action is fired, the result would be pulled from the updated state.

Related