React File Upload - reactjs

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>
);
};

Related

How could I achieve the state update effect in child components immediately?

This is just something I am playing with. Idea was to be able to import JSON data (users) from a remote location, display one user on each click of the button and also be able to delete a user with the delete button.
I have successfully imported JSON into my console and then have been able to show it onto the browser, been able to add users with a click of the button but, I am currently struggling with being able o delete users.
Along with the above, I also had a couple of side questions:
1)- Does creating multiple states affect negatively on the codes' performance in any ways?
2)- Could I have avoided creating count state? I tried with a local variable but that ends up loading from initial value each time the states change. I am sure there must be many ways. Recursion may be one of them which I have just thought of while typing my question and might see how to apply it.
3)- I ended up using id for val in my Blog component because I was failing to be able to access key attribute via event object in handleDel function. How could have I accessed key attribute and if there is any other better approach?
4)- In my count and counter states I tried different initial values but only the below values made the desired effect possible. Why is it so please?
Thanks in advance
import useFetch from './useFetch';
const Blog = ({counter, del}) => {
const {user} = useFetch();
return (
<div>
{
counter.map(val => (
<div key = {val} id={val}>
{user && <p>First name is : {user[val].firstName}</p>}
{user && <p>Last Name is : {user[val].lastName}</p>}
{user && <p>Age is : {user[val].age}</p>}
<button onClick = {del}>Delete</button>
</div>
))
}
</div>
)
}
export default Blog;
import Blog from './Blog';
import { useState } from "react";
const Home = () => {
const [count, setCount] = useState(1);
const [counter, setCounter] = useState([0])
const handleClick = () => {
setCount( count + 1 );
setCounter([...counter,...[count]]);
}
const handleDel = (e) => {
counter.splice(e.target.parentElement.id,1);
}
return (
<div>
hello from home
<button onClick = {handleClick}>Click for us to import a blog</button>
<Blog prp = {{count, counter}} del = {handleDel} />
</div>
)
}
export { Home };

Match background with users current weather conditions

I am new to React, trying to learn and I have this unsolvable problem. I have developed a weather app, I'm still working on it, but at this moment I am stuck for 3 days trying to have a background image that changes depending on the users weather conditions. I have tried something using the icon, from openweather API. I used the same method to get the icon (image from my folder) to match users weather conditions.
import React from "react";
export default function Background(props) {
const codeMapping = {
"01d": "clear-sky-day",
"01n": "clear-sky-night",
"02d": "cloudy-day",
"02n": "cloudy-night",
"03d": "cloudy-day",
"03n": "cloudy-night",
"04d": "cloudy-day",
"04n": "cloudy-night",
"09d": "shower-rain-day",
"09n": "shower-rain-night",
"10d": "rain-day",
"10n": "rain-night",
"11d": "thunderstorm-day",
"11n": "thunderstorm-night",
"13d": "snow-day",
"13n": "snow-night",
"50d": "fog-day",
"50n": "fog-night",
};
let name = codeMapping[props.code];
return (
<img
className="background"
src={`background/${name}.jpg`}
alt={props.alt}
size="cover"
/>
);
}
So... in order to get "icon" of the input city by the user I have to call "<Background cod={weatherData.icon} alt={weatherData.description} />" from the function "Search" which is the function handling the submit form and running api call for input city. But the image is not showing(img1), but to have the img as a background I would call <Background> from my App function(img2), but in this case I will not have access to the real icon value from the input city. I should mention I have a folder in "src" called background and the images names match the codes name from the mapping.
Thank you in advance!
current preview of my app
how I see in other documentation I should set a background
You can pass the code from Search.js as the state.
App.js
const codeMapping = {
"01d": "clear-sky-day",
"01n": "clear-sky-night",
};
export const App = () => {
const [code, setCode] = useState(null) // <-- We'll update this from Search.js
const [backgroundImage, setBackgroundImage] = useState("")
useEffect(() => {
// Set background value based on the code
setBackgroundImage(codeMapping[`${code}`])
}, [code]); // <-- useEffect will run everytime the code changes
return (
<div style={{
height: '100px',
width: '100px',
backgroundImage: `${backgroundImage || "defaultBackgroundImage"}`
}}>
<Search setCode={setCode} />
</div>
)
}
Search.js
import { WeatherContext } from './App';
export const Search = ({ setCode }) => {
const handleClick = (apiResponse) => {
// Some API call returning the actual code value here //
setCode(apiResponse)
}
return (
<input
onClick={() => handleClick("01n")}
type="button"
value="Change city"
/>
)
}

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)
}

React custom hook with state variable as parameter

I have a react function component which sets an array of ids based on an user event on a link click(which opens a popup with some options that can be selected and has a callback once it is closed which will return the id of the selected element). these ids are passed to a child component which has a custom hook which uses these ids to perform some action. whenever i click on the link and select an element and close the popup.. get the error
"VM10715 react_devtools_backend.js:2430 You have changed a parameter while calling a hook which is supposed to remain unchanged [Array(2)]
0: (2) ["", "asdsadsad"]
lastIndex: (...)
lastItem: (...)
length: 1"
is there a way to make this work without running into this error? please see the code sample below
const TestComp = () => {
const [newIds, setNewIds] = useState([]);
const onPopupElementSelect = (ids) => {
setNewIds([...newIds, ids]);
};
return (
//renders some components
<>
<ImageComponent images={images} ids={newIds} onClick={handleClick} />
<Popup onSelect={onPopupElementSelect} />
</>
);
};
const ImageComponent = (props) => {
const { newIds, images } = props;
const newImages = useImages(ids || ['']); //customhook that fetches image details by ids
const imgs = images.map((i) => (
<div key={i.imageId}>
<img src={i.imageUrl} alt="" />
<Link onClick={handleClick} /> //opens the popup for user to select a new
image
</div>
));
return <div>{imgs}</div>;
};
ps: the paramerter names are not the issue.. this code is just a sample to give the basic idea of what i'm trying to do.
I think it is because you gave the same name to parameter and the state may be try newID as the parameter name
const onPopupElementSelect = (newId) => {
setIds(oldIds => [...oldIds, newId]);
};

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

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}
</>
);
}

Resources