Home > Software engineering >  How do you force a child component to re-render on state change?
How do you force a child component to re-render on state change?

Time:12-26

I'm using React and trying to re-render a child custom input component on prop state change but it's not working.

The prop state change is being fired by a button click in the parent component for simplicity in this example, but there are other use cases where I'd like to automatically fire it when a calculation is performed.

Any suggestions on how to make this work is much appreciated. Thanks!

**//Parent Component**

import React,{useEffect, useState} from 'react'
import ChildComponent from '../components/ChildComponent.js'

const ParentComponent = () => {

    const [inputValue, setInputValue] = useState(123)

    const updateInputValue = () =>{
        setInputValue(6789) //<--Child component below is not updating even though the prop state has been updated
    }

    return (
        <div>
            <ChildComponent
                value={inputValue}
                setState={setInputValue}
            /> 

            <button onClick={updateInputValue}>Update</button>     
        </div>
    )
}

export default ParentComponent

====================================================================================

**//Child Component**

import React,{useState} from 'react'

const ChildComponent = (props) => {

      const[inputValue, setInputValue] = useState(props.value)//<--even though this prop state has changed, the input value does not update.  It only works the first time the component is rendered.

      return (
        <div>
          <input 
             value={inputValue} 
             onChange={(e)=>setInputValue(e.target.value)}
             onBlur={(e)=>props.setState(e.target.value)}
          >
          </input>
        </div>
      )
}
export default ChildComponent

CodePudding user response:

You could pass the state and setState from the parent to the children.

Since your child's state depends on the parent component, it would be better to pass the setState to it.

In doing so, you have made your child component stateless, and just a props-driven component.

Do check the sandbox link here too : https://codesandbox.io/s/distracted-golick-bikb1y?file=/src/App.js:0-723

import React, { useState } from "react";

const ParentComponent = () => {
  const [inputValue, setInputValue] = useState(123);

  const updateInputValue = () => {
    setInputValue(6789); //<--Child component below is not updating even though the prop state has been updated
  };

  const onChange = (v) => {
    setInputValue(v);
  };

  return (
    <div>
      <ChildComponent value={inputValue} onChange={onChange} />

      <button onClick={updateInputValue}>Update</button>
    </div>
  );
};

export default ParentComponent;

const ChildComponent = (props) => {
  return (
    <div>
      <input
        value={props.value}
        onChange={(e) => props.onChange(e.target.value)}
      ></input>
    </div>
  );
};

  • Related