Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React – state does not update with useReducer

I want to get the heights of the rendered list items into an array stored in a parent component. It looks fairly simple but still it does not work. From what I see when debugging, the dispatch is fired and the reducer receives the action, but yet the state remains as empty array.

ArticlesMenu.js

import React, { useRef, useState, useEffect, useReducer } from 'react';
import ArticlesMenuItem from './ArticlesMenuItem';

    const reducer = (state, action) => {
        console.log('action', action)
        switch (action.type) {
            case 'add-height': 
                return [...state, action.payload];
            default:
                return state
        }
    }
    
    const ArticlesMenu = ({ articleItems }) => {
        const initialState = [0];
        const [state, dispatch] = useReducer(reducer, initialState);
        const [height, setHeight] = useState('auto'); 
        const renderArticles = () => {
            return articleItems && articleItems.items.map((item, index) => {
                return (
                    <ArticlesMenuItem 
                        path={item.path}    
                        height={height}
                        label={item.label}
                        key={item.id}
                        getHeights={(refHeight) => {
                            console.log('refHeight', refHeight)
                            dispatch({type: 'add_height', payload: refHeight})
                        }}
                    />
                )
            });
        }
    
        console.log('state', state)
    
        return (
            <div id="articles" className="clearfix">
                <h2 className="articles__heading">{articleItems && articleItems.heading}</h2>
                <ul className="articles__list">
                    {renderArticles()}
                </ul>
            </div>
        )
    }
    
    export default ArticlesMenu

ArticlesMenuItem.js

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import { useRef, useEffect, useState } from 'react';
import { Link } from 'react-router-dom';

const ArticlesMenuItem = ({ path, id, label, height, getHeights}) => {
    const ref = useRef();

    useEffect(() => {
        getHeights(ref.current.clientHeight)
    },[])

    return (
        <li className="articles__item" ref={ref} style={{height: height}}>
            <Link to={path} className="articles__link" >{label}</Link>
        </li>
    )
}

export default ArticlesMenuItem;

>Solution :

Your dispatch action type is ‘add_height’ but in your reducer the action type is ‘add-height’ so the way use default that return state and your initial state is an empty array.
You need to change your dispatch action type for same string that reducer annotation.
For not reproduce this error use a reference (const ADD_HEIGHT_ACTION = ‘add-height’ and use on reducer and dispatch.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading