How to populate initial data on click in react

Viewed 141

I working On react Apollo graphql to fetch the data from UI, here I am fetching data from backend and uploading the image, then there is a button (edit) on which click I make the fields editable so that user can upload a new Image.

Issue

On edit click I have two buttons edit and cancel

the issue is When I click cancel it is not taking the initial image.

what I am doing is

const [file, setfile] = useState('');
const [filename, setfilename] = useState('Chose file');
const [canCeldata, setcanCeldata] = useState(null);
const [disabled, setdisabled] = useState(true);
const [edit, setedit] = useState(false);
const [formData, setFormdata] = useState(false);

const { loading, error, data } = useQuery(Get_img);

useEffect(() => {
    if (data) {
        setFormdata(data.getImage);
        setcanCeldata(data.getImage);
    }
}, [data]);
if (loading) return <div>Loadinf</div>;
if (error) return <div>Error</div>;

const onChange = (e) => {
    //  setfile(e.target.files[0]);
    //  setfilename(e.target.files[0].name);
    let file = e.target.files;

    let reader = new FileReader();
    reader.readAsDataURL(file[0]);

    reader.onload = (e) => {
        //  console.log(e.target.result);
        formData.img_url = URL.createObjectURL(file[0]);

        setfile(e.target.result);
    };
};

const Edit = () => {
    setdisabled(false);
    setedit(true);
};
const cancel = () => {
    console.log(data);
    setFormdata(canCeldata);
    setdisabled(true);
    setedit(false);
};


         <form>
            {edit === false && (
                <button className="btn btn-primary" type="button" onClick={Edit}>
                    Edit
                </button>
            )}
            {edit === true && (
                <div>
                    <button className="btn btn-primary" type="button">
                        Save
                    </button>
                    <button className="btn btn-primary" type="button" onClick={cancel}>
                        Cancel
                    </button>
                </div>
            )}
            <br />
            <div className="custom-file">
                <input
                    disabled={disabled}
                    type="file"
                    accept="image/png, image/jpeg"
                    className="custom-file-input"
                    id="customFile"
                    onChange={onChange}
                />
                <label className="custom-file-label" htmlFor="customFile">
                    {filename}
                </label>
                <br />
                <br />

                <button
                    disabled={disabled}
                    type="button"
                    className="btn btn-secondary btn-block"
                    onClick={save_img}>
                    Submit
                </button>
            </div>
        </form>
        <img src={formData.img_url} className="test_img" />
    </div>

On cancel click the issue is showing because url is getting changed, I am using URL.createObjectURL

This one is changing the url

For easy understanding here I am providing my static data.

   let data = {
       "id": "1",
       "img_url": 
   "https://storage.blob.core.windows.net/testimageupload/test.png"
     }

Working code

Code sandbox link

2 Answers

I think your issue is that you're not saving the cancelData when the user first edits the form. Try setting your Edit handler to -

const Edit = () => {
    // Add this line: save the form data in it's original
    // state when the user enters Edit mode.
    setcanCeldata({ ...formData });

    setdisabled(false);
    setedit(true);
};

You are mutating formData directly which is not the correct way in hooks. You should use the set function to change any state that you have defined. Below is the working code and I have mentioned the changes as well

/** @format */

import React, { useState, useEffect } from "react";

function Device_register() {
  const [file, setfile] = useState("");
  const [filename, setfilename] = useState("Chose file");
  const [canCeldata, setcanCeldata] = useState(null);
  const [disabled, setdisabled] = useState(true);
  const [edit, setedit] = useState(false);
  const [formData, setFormdata] = useState(false);

  let data = {
    id: "1",
    img_url: "https://picsum.photos/200/300"
  };

  useEffect(() => {
    if (data) {
      setFormdata(data);
      setcanCeldata(data);
    }
  }, []);

  console.log(JSON.stringify(data));

  const onChange = e => {
    let file = e.target.files;

    let reader = new FileReader();
    reader.readAsDataURL(file[0]);

    reader.onload = e => {
      //    console.log(e.target.result);

     // CHANGES DONE HERE
      let newForm = Object.assign({},formData);
      newForm.img_url = URL.createObjectURL(file[0]);
      setFormdata(newForm);
      //formData.img_url = URL.createObjectURL(file[0]);
      // CHANGES END
      setfile(e.target.result);
    };
  };
  const save_img = () => {
    alert("j");
  };

  const Edit = () => {
    setdisabled(false);
    setedit(true);
  };
  const cancel = () => {
    console.log(data);
    setFormdata(canCeldata);
    setdisabled(true);
    setedit(false);
  };
  return (
    <div className="container">
      <form>
        {edit === false && (
          <button className="btn btn-primary" type="button" onClick={Edit}>
            Edit
          </button>
        )}
        {edit === true && (
          <div>
            <button className="btn btn-primary" type="button">
              Save
            </button>
            <button className="btn btn-primary" type="button" onClick={cancel}>
              Cancel
            </button>
          </div>
        )}
        <br />

        <div className="custom-file">
          <input
            disabled={disabled}
            type="file"
            accept="image/png, image/jpeg"
            className="custom-file-input"
            id="customFile"
            onChange={onChange}
          />
          <label className="custom-file-label" htmlFor="customFile">
            {filename}
          </label>
          <br />
          <br />

          <button
            disabled={disabled}
            type="button"
            className="btn btn-secondary btn-block"
            onClick={save_img}
          >
            Submit
          </button>
        </div>
      </form>
      <img src={formData.img_url} className="test_img" />
    </div>
  );
}

export default Device_register;
Related