#javascript #reactjs #render #setstate
#javascript #reactjs #визуализация #setstate
Вопрос:
Итак, я работаю над своим приложением React, и в какой-то момент мне нужно загрузить некоторые файлы. Поэтому я просто использовал input file
, чтобы заставить его работать. Я установил его отображение none, так как хотел, чтобы при загрузке файла нажимался значок моего вложения.
Проблема: при использовании метода ref все работает нормально, за исключением одной вещи, которая приведена ниже в моей функции hangleFileChange, когда setFiles() устанавливает переменную file, компонент не отображается, и я не вижу файловый массив. но если я сохраню файл просто, как
setFile(event.target.files[0])
Я вижу рендеринг. Но с приведенным ниже кодом компонент не отображается
import React, { useRef, useState } from "react";
const App = () => {
const fileInput = useRef(null);
const [file, setFile] = useState([]);
const handleClick = () => {
fileInput.current.click();
};
const handleFileChange = (event) => {
console.log("Make something");
let newFiles = file;
newFiles.push(event.target.files[0]);
console.log(newFiles);
setFile(newFiles);
};
// This should run on every render
console.log("the files array is ", file);
return (
<div className="patientactions-container">
<input
type="file"
style={{ display: "none" }}
onChange={(e) => handleFileChange(e)}
ref={fileInput}
/>
<div onClick={() => handleClick()}>clck</div>
</div>
);
};
export default App;
Пожалуйста, помогите.
Песочница: https://codesandbox.io/s/kind-breeze-czc3w?file=/src/App.js:0-692
Комментарии:
1. Если я вас правильно понял, вы хотите перенести файл в переменную, не так ли?
2. переменная — это просто временная переменная. Я хочу добавить новый файл, загруженный пользователем, в мой файловый массив. Поэтому я взял временную переменную ‘ne’ и скопировал значения file. Затем я нажал новый файл, а затем SetFile(ne). вы поняли?
3. Позвольте мне опубликовать это в ответе
4. Я изменил код и использовал SetFile ( [ …file, event.target . files[0] ] ); И теперь это рендеринг. Но я все еще не понимаю, почему приведенный выше код не работает.
Ответ №1:
Попробуйте эту версию
const handleFileChange = (event) => {
console.log("Make something");
// Set the ne variable to an array, not file
let ne = [];
ne.push(event.target.files[0]);
// then set it equals file.
ne = file;
console.log(ne);
console.log(file);
setFile(file);
};
Ответ №2:
Вы можете исправить код, подобный приведенному ниже.
import React, { useRef, useState } from "react";
const App = () => {
const fileInput = useRef(null);
const [file, setFile] = useState(null);
const handleClick = () => {
fileInput.current.click();
};
const handleFileChange = (nfile) => {
console.log("Make something");
if (file == null) setFile([nfile]);
else setFile([...file, nfile]);
};
console.log("the files array", file);
return (
<div className="patientactions-container">
<input
type="file"
style={{ display: "none" }}
onChange={(e) => handleFileChange(e.target.files[0])}
ref={fileInput}
/>
<div onClick={() => handleClick()}>clck</div>
</div>
);
};
export default App;
Комментарии:
1. Да, я сделал то же самое, что и выше, и повторный рендеринг выполняется нормально. Но я хочу знать, что не так в моей функции handleFileChange, поскольку она также делает то же самое.
2. это потому, что с самого начала файл пуст, и вы устанавливаете новый файл в пустой массив … помните, что код читается сверху вниз
Ответ №3:
Я бы написал это в комментариях, но моя репутация недостаточно высока.
У меня была проблема с отображением изменений в массиве, поскольку массивы используют указатели, которые не «регистрировали» изменение состояния, которого было достаточно, чтобы вызвать рендеринг. Использование оператора распространения в вашем решении повлияло на указатель, и, таким образом, произошел рендеринг.
В моем собственном решении я установил для своего массива значение null перед добавлением содержимого, и это отлично сработало для моей проблемы.