Search code examples
reactjscomponentsreact-component

React functional component not updating when pushing data to array


I have this functional component which is not updating when pushing data to an array:

const Experience = (props) => {
    let experience = [{
        from:"", 
        to:"",
        employer_name:"",
        employer_number:""
    }];

    function addExperience() {
        experience = [...experience, {
            from:"", 
            to:"",
            employer_name:"",
            employer_number:"",
        }];
    }

    return (
        <>
            {experience.map((val, idx) => {
                let id = `exp-id-${idx}`

                return(
                    <div key={idx} id={id}>
                        ...
                    </div>
                )
            })}
            <button onClick={addExperience}>Add experience</button>
        </>
    )
}

When Add experience is clicked the mapping is not updated, any help?


Solution

  • Although you're updating the variable, the component itself is not rerendering. A functional component will trigger a render when one of its props update.

    In order to get the desired behavior, you have to use state, either with the useState hook or by using a class component with state.

    Functional component with React Hooks

    import React, { useState } from 'react';
    
    const Experience = (props) => {
        const [experience, setExperience] = useState([{
            from:"", 
            to:"",
            employer_name:"",
            employer_number:""
        }]);
    
        function addExperience() {
            setExperience([...experience, {
                from:"", 
                to:"",
                employer_name:"",
                employer_number:"",
            }]);
        }
    
        return (
            <>
                {experience.map((val, idx) => {
                    let id = `exp-id-${idx}`
    
                    return(
                        <div key={idx} id={id}>
                            ...
                        </div>
                    )
                })}
                <button onClick={addExperience}>Add experience</button>
            </>
        )
    }
    

    Class Component

    import React, { Component } from 'react'
    
    class Experience extends Component {
        state = {
            experience: [{
                from:"", 
                to:"",
                employer_name:"",
                employer_number:""
            }]
        };
    
        function addExperience() {
            this.setState([...this.state.experience, {
                from:"", 
                to:"",
                employer_name:"",
                employer_number:"",
            }]);
        }
    
        return (
            <>
                {this.state.experience.map((val, idx) => {
                    let id = `exp-id-${idx}`
    
                    return(
                        <div key={idx} id={id}>
                            ...
                        </div>
                    )
                })}
                <button onClick={this.addExperience}>Add experience</button>
            </>
        )
    }