0

I want to be able to reuse my input form as an edit form, so in the form component I check if there is an id in the url with { useParams }, and if there is, set state of the input fields with the data i get from a function getContact that is passed down with props.

In UseEffect I want to track id but not props, so I just put [id] as a dependency at the end of useEffect. If I add [id, props] I'm not able to set the state of the input fields because it instantly sets it back to the values i get back from getContact() (since there IS an id if I'm editing).

I'm very new to React so I just wonder if there is a better way to do this, or if I should just put // eslint-disable-next-line in my code and get on with my life :-)

    const Form = (props) => {
      const { id } = useParams();
    
      const [input, setInput] = useState({});
    
      useEffect(() => {
        setInput(id ? props.getContact(id) : {});
      }, [id]);
    
      const handleChange = (event) => {
        let value = event.target.value;
        let name = event.target.name;
    
        setInput((prev) => {
          return { ...prev, [name]: value };
        });
      };

... A few more functions and then a return that spits out som JSX
2
  • You must remember that the moment you change the id on the url, the component re-renders... this is based on Router. So this mean you can’t achieve value tracking of id within a component internally. That component will rerender on every id changed Commented Aug 30, 2020 at 19:00
  • I am also not sure why you want to track The value of is if its changed or not. Commented Aug 30, 2020 at 19:02

1 Answer 1

1

Anything that is used within the useEffect should be added to the dependency array. Why not extract the id you want to set instead like this?

const contectId = id ? props.getContact(id) : {};
useEffect(() => {
    setInput(contectId);
  }, [contectId]);

This only works if you store the {} somewhere where it does not change on render: Either like this:

const emptyArray = React.useMemo(() => {}, [])
const contectId = id ? props.getContact(id) : emptyArray;
useEffect(() => {
    setInput(contectId);
  }, [contectId]);

or

const emtyArray = {};
const Form = (props) => {
  const { id } = useParams();

  const [input, setInput] = useState({});

 const contectId = id ? props.getContact(id) : emtyArray;
  useEffect(() => {
    setInput(contectId);
  }, [contectId]);

  const handleChange = (event) => {
    let value = event.target.value;
    let name = event.target.name;

    setInput((prev) => {
      return { ...prev, [name]: value };
    });
    console.log(input);
   };
Sign up to request clarification or add additional context in comments.

5 Comments

Hmm, I tried your solution but it didn't work, the error was gone but the behaviour vas the same as when i added props as a dependency in useEffect, I couldn't edit because the input-field-values was immediately set back to the initial values...
What does getContactId do?
OH MAN, SORRY, this totally worked, I had another bug in another place that kept loading the data over and over that messed everything up. Thank you SO MUCH! One thing though, I don't understand why I need an empty object outside of form, i tried it with just const contectId = id ? props.getContact(id) : {}; and it worked just fine :-D
Great, could you accept the answer then so other can find this answer. Because react checks for shallow comparison, so if the object reference changes, it gets triggered. And with the previous code, you create a new object on every render and that would trigger it on every render, because the reference to the object changed,
Sorry again, I see now why I need the empty object outside the Form, at least I think so. Otherwise I can't use the blank form to add a new contact. Im very new to this, so thank you SO much, this was super helpful!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.