T PHo
T PHo

Reputation: 89

How do I reference a variable in redux store from a component index.js (react.js)

I'm a newbie in redux and react.js,

I am trying to make a button disappear on a component in react.js by putting an if condition on the state variable (articlesTable/index.js), which is connected to the redux library function on another file (actions/actionArticles.js), when a button on articlesTable/index.js is clicked, the component is connected with actions/actionArticles.js and dispatch a function in actions/actionArticles.js, which is called loadMoreData(). The function I am trying to configure the state in redux is,

in articlesActions.js

export const loadMoreArticles = () => async (dispatch,  getState) => {
const lastArticleKey = Object.keys(getState().articlesMap).pop();
const lastArticle = getState().articlesMap[lastArticleKey];

console.log("articleMap", getState().articlesMap);
console.log("Last article", lastArticleKey, lastArticle);

let filteredArticles = {};
const uid = getState().auth.uid;
const userLevel = getState().profile.userLevel;
} else {
    const filteredArticlesArray = [];
    var lastArticleReached = false;
    ...

    var lastArticleInArray = filteredArticlesArray[filteredArticlesArray.length-1];
    if (lastArticleInArray[0]===lastArticleKey) {
        console.log("Bingo, last article reached!");  
        lastArticleReached = true;
    }
    else if (lastArticleInArray[0]!== lastArticleKey)
    {
        console.log("Not last article");  
        lastArticleReached = false;
    }
   
    filteredArticles = Object.fromEntries(filteredArticlesArray.reverse());
}
dispatch({type: LAST_ARTICLE_REACHED, payload: lastArticleReached})

...
};

I dispatch this function with

dispatch({ type: LOAD_MORE_ARTICLES, payload: filteredArticles });

in the code snippet above

The root reducer looks like this, reducers/index.js

import { combineReducers } from 'redux';
import { reducer as formReducer } from 'redux-form';

import articlesStatusReducer from './articlesStatusReducer';

const rootReducer = combineReducers({
    ...
    articlesStatus: articlesStatusReducer,
    form: formReducer,
    ...

});

export default rootReducer;

In articleStatusReducer,

import {LAST_ARTICLE_REACHED} from "../actions/types";

export default function(state = {}, action) {
    switch(action.type) {
        case(LAST_ARTICLE_REACHED):
            console.log(action.payload);
            return action.payload;
        default:
            return state;
    }
}

In the articlesTable/index.js, I connect like this

const mapStateToProps = (state) => {
    
    return {
        articlesMap: state.articlesMap,
        appStatus: state.appStatus,
        profile: state.profile,
        lastArticleReached: state.articlesStatus,
    }
};

const mapDispatchToProps = (dispatch) => {
    return {
        getArticlesWithData: () => dispatch(getArticlesWithData()),
        loadMore: () => dispatch(loadMoreArticles())     
    }
};

export default compose(
    withRouter,
    connect(mapStateToProps, mapDispatchToProps)
)(ArticlesTable)

For some reason, articleStatus isn't recognised and when I do

console.log(this.props.articleStatus)

state.articleStatus is undefined

How can I reference state.articleStatus which should be boolean ?

Edit: For some reason when I put it in a conditional JSX brackets in the render method, it prints out undefined

render () => {
{
console.log(this.props.lastArticleReached), 
!this.props.lastArticleReached 
: <Button> </Button>
?
<div><div>
}
}``

Upvotes: 0

Views: 1545

Answers (2)

T PHo
T PHo

Reputation: 89

I tried another name for the props but with similar method as Thomas Caillard,

Reducer.js

case(REACH_LAST_ARTICLE):
            return  {...state, lastArticleReached: action.payload}

in component index.js

const mapStateToProps = (state) => {
    return {
        ...
        lastArticleReached: state.articlesMap.lastArticleReached
        ...
    }
};

Thanks for all the helps so far

Upvotes: 0

Thomas Caillard
Thomas Caillard

Reputation: 11

In function mapStateToProps, you should map state.articleStatus to a props.

somethings like this:

    const mapStateToProps = (state) => {
    return {
        articlesMap: state.articlesMap,
        appStatus: state.appStatus,
        profile: state.profile,
        lastArticleReached: state.articlesStatus,
        articleStatus: state.articleStatus
      }
  };

So this.props.articleStatus will works . :)

The problem is in your reducer. Each case of your reducer must return the state but in your case, your return action.payload.

try something like this.

case(LAST_ARTICLE_REACHED):
        console.log(action.payload);
        return {...state, articleStatus: action.payload};

like this, articlesStatus became an object with one props, articleStatus, your boolean.

Upvotes: 1

Related Questions