1

I have created dynamic fields from JSON data, and I am successfully rendering on UI

  • Initially all the fields are disabled.
  • Once I click on edit I am making particular row editable which is working fine
  • On click of cancel what I want to do is make the fields disabled again and it should take the previous (initial value)

Issue

When I click on cancel I am setting the initial data aging but it is not taking, I am using react-form-hook for form validation, there we have reset() function but that too is not working.

What I am doing is

Getting data from main component and setting it to some state variable like below

    useEffect(() => {
    if (li) {
      setdisplayData(li);
      setCancelData(li);
    }
  }, [li]);
  • Now using displayData to render the elements

    On click of Edit I am doing this

    const Edit = () => { setdisabled(false); };

and on click of cancel I am doing below

const cancel = () => {
    setdisabled(true); //disbaled true
    console.log(cancelData);
    setdisplayData(cancelData); setting my main data back to previous one
    reset(); // tried this reset of react hook form but it did not work
  };

I am using defaultValue so that when I click on Edit the field should allow me to edit.

Here is my full working code

vivek singh
  • 417
  • 2
  • 12
  • 36

1 Answers1

1

To fix this issue I changed up your code to use value instead of defaultValue. Additionally added an onChange event handler which updates the displayData state whenever <input> changes value. Moreover, you do not need the cancelData state at all since the li prop has the original values.

Now when the onClick for the cancel button is fired, it resets the value of displayData state to whatever li originally was. Here is the modified code:

import React, { useState, useEffect } from "react";
import { useForm } from "react-hook-form";

function component({ li, index }) {
  const [disabled, setdisabled] = useState(true);
  const [displayData, setdisplayData] = useState(null);
  const { register, reset, errors, handleSubmit, getValues } = useForm();

  useEffect(() => {
    if (li) {
      setdisplayData(li);
    }
  }, [li]);

  const Edit = () => {
    setdisabled(false);
  };

  const cancel = () => {
    setdisabled(true);
    console.log(li);
    // Reset displayData value to li
    setdisplayData(li);
    reset();
  };
  return (
    <div>
      <div>
        {disabled ? (
          <button className="btn btn-primary" onClick={Edit}>
            Edit
          </button>
        ) : (
          <button className="btn btn-warning" onClick={cancel}>
            Cancel
          </button>
        )}
      </div>
      <br></br>

      {displayData !== null && (
        <>
          <div className="form-group">
            <label htmlFor="fname">first name</label>
            <input
              type="text"
              name="fname"
              disabled={disabled}
              value={displayData.name}
              // Update displayData.name everytime value changes
              onChange={({ target: { value } }) =>
                setdisplayData((prev) => ({ ...prev, name: value }))
              }
            />
          </div>
          <div className="form-group">
            <label htmlFor="lname">last name</label>
            <input
              type="text"
              name="lname"
              disabled={disabled}
              value={displayData.lname}
              // Update displayData.lname everytime value changes
              onChange={({ target: { value } }) =>
                setdisplayData((prev) => ({ ...prev, lname: value }))
              }
            />
          </div>
        </>
      )}

      <hr></hr>
    </div>
  );
}

export default component;

Hope this helps. Drop a comment if it's still not clear :)

sudo97
  • 904
  • 2
  • 11
  • 22
  • Have you got the issue why it is not working with `defaultValue` ? – vivek singh Nov 26 '20 at 07:01
  • The `defaultValue` attribute simply stores the initial value of the input tag. Whereas `value` stores the current value of the input tag. Traditionally you would use the `defaultValue` and `value` attributes to compare what has changed in the input value. In your react code, you have the default value in the `li` prop so its not necessary here to set `defaultValue`. – sudo97 Nov 26 '20 at 07:26
  • Hey could you please help me in this https://stackoverflow.com/questions/69703295/how-to-achieve-hash-routing-in-react-with-scrollspy I have been stuck here for so long. – vivek singh Oct 25 '21 at 14:41