#redux #file-upload
#сокращение #загрузка файла
Вопрос:
Я хочу, чтобы при нажатии на один значок загружалось только одно изображение. Вместо этого все значки обновляются, когда я пытаюсь загрузить одно изображение только на один значок изображения. Может кто-нибудь помочь мне разобраться в этом. У меня такое чувство, что это потому, что я не использую уникальные идентификаторы для входного идентификатора, но я не уверен. Любая помощь будет оценена. Спасибо.
import React, { useState } from "react";
import { Row, Col } from "../Grid";
import PropTypes from 'prop-types';
export default function Step1(props) {
const [image_1, setImage_1] = useState({ preview_1: "", raw_1: "" });
const [image_2, setImage_2] = useState({ preview_2: "", raw_2: "" });
const [image_3, setImage_3] = useState({ preview_3: "", raw_3: "" });
const [image_4, setImage_4] = useState({ preview_4: "", raw_4: "" });
const handleLoadLocalFile = (event) => {
event.preventDefault();
const file_1 = event.target.files[0];
const file_2 = event.target.files[0];
const file_3 = event.target.files[0];
const file_4 = event.target.files[0];
const localImageUrl_1 = window.URL.createObjectURL(file_1);
const localImageUrl_2 = window.URL.createObjectURL(file_2);
const localImageUrl_3 = window.URL.createObjectURL(file_3);
const localImageUrl_4 = window.URL.createObjectURL(file_4);
if(event.target.files.length){
setImage_1({
preview_1: localImageUrl_1,
raw_1: file_1
})
setImage_2({
preview_2: localImageUrl_2,
raw_2: file_2
})
setImage_3({
preview_3: localImageUrl_3,
raw_3: file_3
})
setImage_4({
preview_4: localImageUrl_4,
raw_4: file_4
})
props.onFileLoaded(localImageUrl_1);
props.onFileLoaded(localImageUrl_2);
props.onFileLoaded(localImageUrl_3);
props.onFileLoaded(localImageUrl_4);
}
}
const handleUpload = async event => {
event.preventDefault();
const formData = new FormData();
formData.append("image_1", image_1.raw_1)
formData.append("image_2", image_2.raw_2)
formData.append("image_3", image_3.raw_3)
formData.append("image_4", image_4.raw_4)
}
if(props.currentStep !== 1) {
return null;
}
// const [image, setImage] = useState({ preview: "", raw: "" });
// const handleItemChange = e => {
// if (e.target.files.length) {
// setImage({
// preview: URL.createObjectURL(e.target.files[0]),
// raw: e.target.files[0]
// });
// }
// };
// const handleItemUpload = async e => {
// e.preventDefault();
// const formData = new FormData();
// formData.append("image", image.raw);
// await fetch("/api/additem", {
// method: "POST",
// headers: {
// "Content-Type": "multipart/form-data"
// },
// body: formData
// });
// };
//Markup for step 1 UI
return(
<Row>
<Col size="md-6">
<div>
<label htmlFor="upload-button" id="file_1">
{image_1.preview_1 ? (
<img src={image_1.preview_1} alt='dummy' width="100" height="100" />
) : (
<img src={require("../../images/store.jpg")} style={{justifyContent: "center", alignItems: "center"}} alt="placeholder" width="100" height="100" />
/* // <>
// <span className="fa-stack fa-2x mt-3 mb-2">
// <i className="fas fa-circle fa-stack-2x" />
// <i className="fas fa-store fa-stack-1x fa-inverse" />
// </span>
// {/* <h5 className="text-center">Upload your photo</h5>
// </> */
)}
</label>
<input
type="file"
id="upload-button"
style={{ display: "none" }}
value={props.localImageUrl_1}
onChange={handleLoadLocalFile} />
<br/>
<button onClick={handleUpload}>Upload</button>
</div>
<div>
<label htmlFor="upload-button" id="file_2">
{image_2.preview_2 ? (
<img src={image_2.preview_2} alt="dummy" width="100" height="100" />
) : (
<img src={require("../../images/store.jpg")} style={{justifyContent: "center", alignItems: "center"}} alt="placeholder" width="100" height="100" />
/* // <>
// <span className="fa-stack fa-2x mt-3 mb-2">
// <i className="fas fa-circle fa-stack-2x" />
// <i className="fas fa-store fa-stack-1x fa-inverse" />
// </span>
// {/* <h5 className="text-center">Upload your photo</h5>
// </> */
)}
</label>
<input
type="file"
id="upload-button"
style={{ display: "none" }}
value={props.localImageUrl_2}
onChange={handleLoadLocalFile} />
<br />
<button onClick={handleUpload}>Upload</button>
</div>
<br />
<div>
<label htmlFor="upload-button" id="file_3">
{image_3.preview_3 ? (
<img src={image_3.preview_3} alt="dummy" width="100" height="100" />
) : (
<img src={require("../../images/store.jpg")} style={{justifyContent: "center", alignItems: "center"}} alt="placeholder" width="100" height="100" />
/* // <>
// <span className="fa-stack fa-2x mt-3 mb-2">
// <i className="fas fa-circle fa-stack-2x" />
// <i className="fas fa-store fa-stack-1x fa-inverse" />
// </span>
// {/* <h5 className="text-center">Upload your photo</h5>
// </> */
)}
</label>
<input type="file"
id="upload-button"
style={{ display: "none" }}
value={props.localImageUrl_3}
onChange={handleLoadLocalFile} />
<br />
<button onClick={handleUpload}>Upload</button>
</div>
<div>
<label htmlFor="upload-button" id="file_4">
{image_4.preview_4 ? (
<img src={image_4.preview_4} alt="dummy" width="100" height="100" />
) : (
<img src={require("../../images/store.jpg")} style={{justifyContent: "center", alignItems: "center"}} alt="placeholder" width="100" height="100" />
/* // <>
// <span className="fa-stack fa-2x mt-3 mb-2">
// <i className="fas fa-circle fa-stack-2x" />
// <i className="fas fa-store fa-stack-1x fa-inverse" />
// </span>
// {/* <h5 className="text-center">Upload your photo</h5>
// </>
)} */
)}
</label>
<input
type="file"
id="upload-button"
style={{ display: "none" }}
value={props.localImageUrl_4}
onChange={handleLoadLocalFile} />
<br />
<button onClick={handleUpload}>Upload</button>
</div>
</Col>
<Col size="md-6" fixed>
<form>
<label htmlFor="title">Title:</label>
<input
onChange={props.handleChange}
value={props.title}
name="title"
type="text"
className="form-control"
placeholder="product title"
id="title"
/>
<br/>
<br/>
<br/>
<label htmlFor="price">Price:</label>
<input
onChange={props.handleChange}
value={props.price}
name="price"
type="text"
className="form-control"
placeholder="product price"
id="price"
/>
<br/>
<br/>
<br/>
<label htmlFor="shelf">Shelf:</label>amp;nbsp;amp;nbsp;
<select
onChange={props.handleChange}
value={props.shelf}
name="shelf"
id="shelf"
>
<option value="biscuits">Biscuits</option>
<option value="breads">Breads</option>
<option value="cakes">Cakes</option>
<option value="pastries">Pastries</option>
<option value="pizzas">Pizzas</option>
<option value="signature">Signature</option>
</select>
</form>
</Col>
</Row>
)
}
Step1.propTypes = {
onFileLoaded: PropTypes.func.isRequired
}
// export default Step1;
Ответ №1:
Ваша onClick
функция одинакова handleClick
для каждого изображения. Вызов этой функции добавляет все четыре файла formData
, вызывая их загрузку.
const handleUpload = async event => {
event.preventDefault();
const formData = new FormData();
formData.append("image_1", image_1.raw_1)
formData.append("image_2", image_2.raw_2)
formData.append("image_3", image_3.raw_3)
formData.append("image_4", image_4.raw_4)
}
Вам нужна функция, которая принимает изображение для добавления в качестве аргумента и добавляет только это одно изображение.
Вы создали много ненужных повторений кода, обрабатывая четыре изображения как отдельные состояния. Подумайте о том, как вы можете выполнить цикл от 1 до 4 и сделать то же самое для каждого числа. И как иметь функции, которые принимают число в качестве аргумента.
A handleUpload
может выглядеть примерно так, если все 4 изображения были сохранены в массиве.
const handleUpload = id => async event => {
event.preventDefault();
const formData = new FormData();
formData.append(`image_${id}`, images[id].raw)
}