React app - upload and read JSON file into variable without a server? - reactjs

I'm building a JSON editor in React and right now I'm just fetching a json file from a static folder on the server and sticking it in a variable. I'd like to be able to use a file input and select any json file and read it into the variable.
Is this possible without a server?
That said, I also tried using an Express/Cors server but it's a bit outside my wheelhouse and I'm not sure how to install / run it on the production domain where this editor will live.

Have an input of type file and maintain a state and update the state upon onChange
working demo is here
Code snippet
import React, { useState } from "react";
export function Upload({ children }) {
const [files, setFiles] = useState("");
const handleChange = e => {
const fileReader = new FileReader();
fileReader.readAsText(e.target.files[0], "UTF-8");
fileReader.onload = e => {
console.log("e.target.result", e.target.result);
setFiles(e.target.result);
};
};
return (
<>
<h1>Upload Json file - Example</h1>
<input type="file" onChange={handleChange} />
<br />
{"uploaded file content -- " + files}
</>
);
}

Related

React File Upload

I just want to create simple file upload component on react. It will be something simple that after select the file and submit the upload button, it will give a massage with filename like "You uploaded fileName.txt". I have tried search so many sources but it's mostly more than I need, that would be great if anyone could help me about it. Thank you!
You can detect file selection using the onChange event listener, and you can access the name of the selected file via e.target.files which returns all of the files which have been selected, we'll take the first selected file and store its name value inside a state called selectedFileName.
during render we'll check if the selectedFileName state has value, we'll display it inside a p tag.
import React, { useState } from 'react';
export const App = () => {
const [selectedFileName, setSelectedFileName] = useState('');
const [displayFileName, setDisplayFileName] = useState(false);
const submitFile = () => setDisplayFileName(true);
const handleFileSelect = e => {
const selectedFile = e.target.files[0];
setDisplayFileName(false);
setSelectedFileName(selectedFile?.name);
};
return (
<div>
<input
type='file'
accept='*'
name='fileSelect'
onChange={handleFileSelect}
/>
{displayFileName ? (
<p>{ selectedFileName?`You Uploaded '${selectedFileName}'`:"Please select a file!"}</p>
) : (
<button value='Submit' onClick={submitFile}>
Submit File
</button>
)}
</div>
);
};

Cannot map through array of files/images React

I am creating an image(s) upload component in React. Every time the file input field changes I am updating the images state. Below the input field I am trying to loop through the images and log their names in the console. However, as soon as I select an image, I get the error TypeError: images.map is not a function.
Here is my code:
import React, { useState } from 'react';
const ImagesInput = (props) => {
const [images, setImages] = useState([]);
const imageInputChange = (e) => {
setImages(e.target.files)
}
return (
<div>
<input {...props} type="file" onChange={imageInputChange} multiple />
{images.map((image) => {
console.log(image)
})}
</div>
)
}
export default ImagesInput;
The value of e.target.files is an array-like not an actual array. Just convert it to array before passing to setImages, like
setImages([...e.target.files])
Read here about array-like
Before
setImages(e.target.files)
Try to add a condition like this, make sure e.target.files is the image arr you want
if(e.target.files){
setImages(e.target.files)
}

How to do useState in this case, I can't add component with props

I learn ReactJs and JavaScript and got stuck a bit
If I do like this:
const [data, setData] = useState([]);
const addData = val => {
setData([...data, val]);
};
It work as expected every time I run that addData the data will have one more val merging into it ok
But when I like this:
const addData = val => {
setData([...data, File: file={val}]);
};
And the File is this simple:
const File = (file) => {
const classes = useStyles();
// do stuff
return (
<Return something with props file />
);
};
export default File;
Then I get error I don't know how to give val to File before I add File to data
I tried like (File: File={val}) but no
The main issue is with File: file={val}. You have an array of objects so you should add a new object rather then a property. for that. you need to add this into a {}. Second, when creating a structure and asaigning values, use : not =. and 3rd - dont suround ur val in {}. Make it a simple val. If you wish to pass data to val, assuming it some sort of component, make it into an arrow function and load it as a component () => <Val />. NOTE, it has to start with a capital letter.
Here is a demo I made similar to what you want by my understandings.
import { useState } from "react";
export default function App() {
const [data, setData] = useState([]);
const File = ({ file }) => {
return <div>{file}</div>;
};
const clickMe = () => {
setData([...data, { File: () => <File file={"some file name"} /> }]);
};
return (
<div className="App">
<button onClick={clickMe}>Add</button>
{data && data.map(({ File }, i) => <File key={i} />)}
</div>
);
}
Whenever you click a button, a new component, called File will be added to state data and will pass a prop file into it. and in render all the data form data will be rendered.
NOTE You may use File: <File file={"some file name"} /> instead of using an arrow function File: () => <File file={"some file name"}. But this may create some issues and will load the component File when adding it to data instead of loading in render. hence an arrow function is a better and recomended way to go.
Live example: https://codesandbox.io/s/festive-sea-svhbs?file=/src/App.js:0-441

How to show uploaded files using initialFiles on material-ui-dropzone?

I am using reactjs and trying to show my uploaded files in preview area of material-ui-dropzone.
First I fetch my uploaded files (just their name) from server and then set it into state. I set initialFiles={uploadedFiles} but my uploaded files not show in preview area. How can I fix that?
My code:
import { DropzoneArea } from "material-ui-dropzone";
export function UploadedFileDropzone(props) {
const [uploadedFiles, setUploadedFiles] = useState([]);
function getUploadedFiles() {
// const files = fetch file names from server
setUploadedFiles(files);
}
useEffect(() => {
getUploadedFile();
}, []);
return (
<div>
<DropzoneArea initialFiles={uploadedFiles}/>
</div>
)
}
Here is what I had and what I expect
There is a property of "DropzoneArea" called 'useChipsForPreview' by default it's false set it to true you will get the desire output

Storing uploaded file in state variable wont work. React

I am trying to store an uploaded file in a state variable that I will post to the DB once the user has completed the rest of the form. For some reason, my state wont update and my state variable is left null. I am calling onChange and passing it my onChange function to store the file in state. I put some comments in the code. Can anyone help please?
interface PostState {
file: File
//i have tried multiple data types for the file variable, still no luck
}
const Form = (props) => {
const defaultPostState: PostState = {
file: null,
//i have also tried setting this to undefined or not setting a default value at all as well
}
const [postState, setPostState] = useState(defaultPostState)
const onChange = (e) => {
setPostState({...postState, file: e.target.files[0]})
//this is what wont work - i have debugged it and logged it, it wont store the target file in file
}
<div className='form-group'>
<label>Upload file</label>
<input
id='file'
className='form-control-file'
type='file'
name='file'
ref={register}
onChange={onChange}
/>
</div>

Resources