skip to Main Content

The following ReactJS code doesn’t seem to work. I am expecting the child component to take error as a prop and immediately assign it to the local errorState; howwever, the state never is updated. Please consider:

import { useState } from "react"


const ApiMultiComboNew = (props) => {
    const { error,...nprops } = props;
    const [errorState, setErrorState] = useState(error)
    return <>
        <span>Passed error prop: {error}</span><br /><br />
        <span>Local Error State:  {errorState}</span>
    </>
}
const App = () => {
    const [formState,setFormState] = useState({})    
    const handleClick = (e) => {        
        setFormState(ps=>({...ps,recipients:"This Error Should Show Up"}))        
    }
    return (
        <div style={{width: "500px",height:"200px",border:'1px solid #000',padding:"8px",backgroundColor:"lightblue",margin:"0 auto"}}>
            <div>
                <ApiMultiComboNew error={formState.recipients || ""} />
            </div> 
            <button onClick={handleClick}>Press To Set The Error!</button>
        </div>
    )
}

errorState Doesn’t get assigned no matter how many times I click that little button. Any help appreciated.

CodeSandbox

2

Answers


  1. The issue you’re encountering in your ReactJS code is related to how state and props are managed in React, specifically with the useState hook.

    In your ApiMultiComboNew component, you’re initializing errorState with the error prop using the useState hook

    This initialization happens only once when the component is first rendered. The useState hook does not automatically update the state when the prop changes. This is why errorState does not reflect subsequent changes to the error prop after the component is mounted.

    To solve this issue, you need to synchronize the errorState with the error prop. One way to do this is by using the useEffect hook, which can observe changes in the error prop and update errorState accordingly:

    import { useState, useEffect } from "react";
    
    const ApiMultiComboNew = (props) => {
        const { error } = props;
        const [errorState, setErrorState] = useState(error);
    
        useEffect(() => {
            setErrorState(error);
        }, [error]); // This effect runs whenever 'error' prop changes
    
        return (
            <>
                <span>Passed error prop: {error}</span><br /><br />
                <span>Local Error State: {errorState}</span>
            </>
        );
    };
    

    With this change, whenever the error prop changes, the useEffect hook will be triggered, and the errorState will be updated to reflect the new value of the error prop. This way, your child component’s state will stay in sync with the prop passed from the parent component.

    Also To specifically improve the performance of the ApiMultiComboNew component, the key is to minimize unnecessary re-renders and state updates. However, given the simplicity of your component, there’s limited scope for significant performance improvements. But we can still apply:

    Wrap your component with React.memo to prevent unnecessary re-renders when the props have not changed.

    import React from 'react';
    
    const ApiMultiComboNew = React.memo(({ error }) => {
        return (
            <>
                <span>Passed error prop: {error}</span><br /><br />
                <span>Local Error State: {error}</span>
            </>
        );
    });
    
    
    Login or Signup to reply.
  2. The useState hook uses the variable you pass (in this case error prop) as an initialState, the argument is ignored after the initial render. So, the errorState will initial be "" in this case. No matter how many times the error prop changes, the hook will ignore it. If you want to update the error state everytime the prop changes you need to use the useEffect hook:

     useEffect(() => {
        setErrorState(error)  
     },[error])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search