0

I had an issue getting a component to update when it´s props changed. I got it to work using useEffect, but am unsure if it is the correct way to solve my problem.

This is my code:

import * as React from "react";
import "./styles.css";

const InputWithDefaultValue = (props: any) => {
  const { value } = props;

  //had to add this to get my component to rerender when the button in App-Component was pressed
  React.useEffect(() => {
    setText(value);
  }, [value]);

  const [text, setText] = React.useState(value);

  return (
    <input
      value={text}
      onChange={(e) => setText(e.currentTarget.value)}
    ></input>
  );
};

export const App = () => {
  const [value, setValue] = React.useState("Foo");
  return (
    <div className="App">
      <InputWithDefaultValue value={value} />
      <button onClick={() => setValue(Math.random().toString())}>Update</button>
    </div>
  );
};
export default App;

I was thinking when I updated the props of InputWithDefaultValue it would get rerendered. Is using useEffect to get the component to rerender the correct way to solve the problem or did I find some hacky-solution?

Thanks!

Phil
  • 135
  • 8
  • Is the value just the default value? you should ask yourself if you need both props and local state for the same value. if both this component and the parent component update the value then you can optionally pass in the `setValue` function from the parent that's updating the value instead of having local state here. – Matt Aft Sep 09 '20 at 16:25
  • So when you click the button to update the props, it's not changing? Works for me: [blitz](https://stackblitz.com/edit/react-ts-yrp1kx?file=Hello.tsx) – Jason Goemaat Sep 09 '20 at 16:30

2 Answers2

0

Your solution is correct.

When you add state to a component (i.e. with useState) then the component will no longer automatically update when its props change. Rather, you'd have to use an effect and update an internal state, exactly as you have in your code.

Here's a related question: React.useState does not reload state from props

Arash Motamedi
  • 9,284
  • 5
  • 34
  • 43
  • That's not really true; adding state (via a hook or in class components) doesn't cause a change in rendering behavior. Copying the initial prop to stage causes the "lockdown". – AKX Sep 09 '20 at 16:11
  • @AKX Thanks, can you expand or share a link where I can read more? – Arash Motamedi Sep 09 '20 at 16:13
  • I'm not sure what there is to expand honestly :) – AKX Sep 09 '20 at 16:47
0

You've basically "forked props into state" - at that point you're responsible for taking care of the state changes yourself. Another option might be to to have state for user-edited text, undefined by default, and do something like value={userText !== undefined ? userText : props.value}

AKX
  • 152,115
  • 15
  • 115
  • 172