Reputation: 37
I'm building out this simple image editor, where you can upload an image from your drive and then filter it with various css properties. The file upload part is in a component called FileUpload, and is a child of the App. My problem is that i need a state of the FileUpload to be accesible within the App.js to render the picture. This is the return of the App component:
return (
<div className="container">
<div className="file-upload">
<FileUpload />
</div>
<div style={getImageStyle()} className="main-image" />
<div className="sidebar">
{options.map((option, index) => {
return (
<SidebarItem
key={index}
name={option.name}
active={index === selectedOptionIndex}
handleClick={() => setSelectedOptionIndex(index)}
/>
);
})}
</div>
<Slider
min={selectedOption.range.min}
max={selectedOption.range.max}
value={selectedOption.value}
handleChange={handleSliderChange}
/>
</div>
);
Now i need a state that is inside the FileUpload component:
const [file, setFile] = useState("");
const [filename, setFilename] = useState("Choose File");
const [uploadedFile, setUploadedFile] = useState({});
const [message, setMessage] = useState("");
const [uploadPercentage, setUploadPercentage] = useState(0);
const onChange = (e) => {
setFile(e.target.files[0]);
setFilename(e.target.files[0].name);
};
const onSubmit = async (e) => {
e.preventDefault();
const formData = new FormData();
formData.append("file", file);
try {
const res = await axios.post("/upload", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
onUploadProgress: (progressEvent) => {
setUploadPercentage(
parseInt(
Math.round((progressEvent.loaded * 100) / progressEvent.total)
)
);
// Clear percentage
setTimeout(() => setUploadPercentage(0), 10000);
},
});
const { fileName, filePath } = res.data;
setUploadedFile({ fileName, filePath });
setMessage("File Uploaded");
} catch (err) {
if (err.response.status === 500) {
setMessage("There was a problem with the server");
} else {
setMessage(err.response.data.msg);
}
}
};
return (
<Fragment>
<form onSubmit={onSubmit}>
<div>
<input
type="file"
className="custom-file-input"
id="customFile"
onChange={onChange}
/>
<label className="custom-file-label" htmlFor="customFile">
{filename}
</label>
</div>
<Progress percentage={uploadPercentage} />
<input
type="submit"
value="Upload"
className="btn btn-primary btn-block mt-4"
/>
</form>
{uploadedFile ? (
<div className="row mt-5">
<div className="col-md-6 m-auto">
<h3 className="text-center">{uploadedFile.fileName}</h3>
<img style={{ width: "100%" }} src={uploadedFile.filePath} alt="" />
</div>
</div>
) : null}
</Fragment>
);
};
Now i would need the uploadedFile state to be accesible within the App because i need that file to set the background image of the div <div style={getImageStyle()} className="main-image" />
Would be possible to use useContext, or i should move all the state and logic inside the parent App?
Thank you very much for the help
Upvotes: 0
Views: 38
Reputation: 312
what about declaring a prop in FileUpload
which is a callback called when the file is uploaded and passes the file back to App
?
so something like <FileUpload onComplete={fileUploadedHandler}/>
?
Upvotes: 0