Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Component doesn't re-render when props change using useState hook

Everytime I get new data in data prop but the component dont re-render untill I call handlePanelSelection()

function StepPanel({ data, getTranslations }) {
  const [panelsData, changePanel] = useState(data);

  function handlePanelSelection(panelId) {
    switch (panelId) {
      case 8:
        changePanel(getTranslations.NeeSubCategory);
        break;
      default:
        changePanel(data);
        break;
    }
  }
  return (
    <>
      {panelsData.map(details => {
        const imgsrc = requireContext('./' + details.image);
        return (
          <div key={details.id} className="block-list">
            <div className="left-block">
              <img src={imgsrc} alt="" />
            </div>
            <div className="right-block">
              <h3>{details.title}</h3>
              <p>{details.description}</p>
              <label htmlFor="radio1" className="radio-btn">
                <input
                  type="radio"
                  onClick={() => handlePanelSelection(details.id)}
                  name="radio1"
                />
                <span></span>
              </label>
            </div>
          </div>
        );
      })}
    </>
  );
}

but when I remove the hook like below it works

function StepPanel({ data, getTranslations }) {
 
  return (
    <>
      {data.map(details => { ... })}
    </>
         )
}

I want to implement a functionality that when I get new data in data props the component gets re-render but also when I need to internally re-render i.e. like I change panelId = 8, then also it gets re-render, is it possible with this approach?

The above code seems to rerender but with the same data every time i.e. Its not updating the panelData everytime although everytime the data props is being provided with a new updated value

console image

like image 842
Adarsh Avatar asked Nov 16 '19 07:11

Adarsh


People also ask

Does component re-render if props change?

There are four reasons why a component would re-render itself: state changes, parent (or children) re-renders, context changes, and hooks changes. There is also a big myth: that re-renders happen when the component's props change. By itself, it's not true (see the explanation below).

Does useState hook trigger a Rerender?

As we already saw before, React re-renders a component when you call the setState function to change the state (or the provided function from the useState hook in function components). As a result, the child components only update when the parent component's state changes with one of those functions.

Why does React not Rerender on state change?

In these cases, React doesn't trigger a re-render because the state did not change. If the current day is 5, it will be the exact same value as long as the number is the same. Once it changes, React will immediately receive the update and trigger a re-render.

Why is useState not updating?

If you find that useState / setState are not updating immediately, the answer is simple: they're just queues. React useState and setState don't make changes directly to the state object; they create queues to optimize performance, which is why the changes don't update immediately.


1 Answers

This is because when you do this:

const [panelsData, changePanel] = useState(data);

You're only using your data prop as the initial value of panelsData. When the props change, the new data will be ignored because panelsData has its own state (well, it's a useState hook!).

That's why you have to explicitly call changePanel to change the state. That's the whole idea!

If you want to observe the data prop and update the state accordingly, you could use a useEffect hook with data as dependency (that means, it'll run only when data changes), like this:

useEffect(() => {
  changePanel(data);
}, [data]);
like image 175
ezakto Avatar answered Sep 19 '22 15:09

ezakto