0

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>
}
}``
3
  • Both the messages are contradictory. You write this: console.log(this.props.articleStatus) but you get state.articleStatus is undefined? How is this possible? Commented Nov 23, 2020 at 10:03
  • Sorry, my bad. I understood the question wrong. Check out the other answers, I'll delete my answer. Commented Nov 23, 2020 at 10:33
  • My bad, I mean when I logged the value, it was undefined Commented Nov 23, 2020 at 10:34

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

lastArticleReached: state.articlesStatus, articleStatus: state.articleStatus Are these two lines map the same thing?
state.articlesStatus != state.articleStatus. there is a 's' at the end of article. i suppose, there are articlesStatus and articleStatus in your state.
It's strange even though I get some boolean values when I do console.log for state.articleStatus but when I try to console.log in the render method, it printed "undefined". Check my edit post
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.