Search code examples
javascriptreactjsfile-upload

Can I save an image in 'public' folder using react?


I am studying MERN and my tutor has given me an assignment: Store image given by user in the 'public' folder without the use of backend or database, just react. I have:

import { useEffect, useState } from "react";

export default function App() {
  const [image, setImage] = useState(null);
  const [file, setFile] = useState(null);

  useEffect(() => {
    if (file) {
      var src = URL.createObjectURL(file[0]);
      setImage(
        <img src={src} />
      );
    }
  }, [file])

  return (
    <div>
      <input type="file" onChange={(e) => setFile(e.target.files)} />
      { image }
    </div>
  );
}

I can't seem to figure out the way to store the image the way my tutor wants me to do it.


Solution

  • I take it that you are referring to Create-React-App (CRA) and its convention of using "%PUBLIC_URL%" to access the public folder you are talking about.

    All of these files are sent to the browser and the browser does not offer a convenient filesystem you can write to. It only gives an API that can be used to write to the filesystem of the OS (keep in mind that you need permission from the user to do this).


    When you run the server CRA offers, CRA bundles a development build of these files and sends to the browser. [1] When there is any change to any of the files, it rebuilds everything and communicates to the browser via Websocket that there are new changes. The client then requests the new files which are sent to the client over HTTP. [2] CRA at this point maintains a WebSocket connection with the browser so that this file communication will be efficiently handled.

    You can now see the problem in the rationale of the question. When you create a static build of this app, it will bundle all the files and there will be no hot reloading feature any more. You can serve it with any static file server and the files will end up living in the client’s browser. There will be no public folder anymore. [3]

    The question is based on a fundamental misunderstanding of how CRA works.


    [1] Static resource importing, tree-shaking e.t.c are done by Webpack under the hood.

    [2] This feature is called hot-reloading.

    [3] You can try this for yourself to see what I’m talking about.