问题:当props.files
被控制台记录时(查看下面的代码以查看它的记录位置),它第一次工作。但是,当我选择一组新文件时,它再也不会控制台记录任何内容,除非我重新加载页面并重新开始。我在这里做错了什么?
我的代码信息:
我使用React Bootstrap Form Components(滚动到"File Input")用于以下自定义组件(即Form.Group、Form.Label、Form.Control)。为了清晰起见,代码被大大简化:
const UploadFile = (props) => {
// stuff here
console.log(props.files);
const filesFunction = (filesInput) {
// do stuff with filesInput
}
return {
<Form.Group controlId="formFileMultiple" className="mb-3">
<Form.Label> Files </Form.Label>
<Form.Control
type="file" multiple
onChange={props.handleFilesChange}
onChange={filesFunction(files)}
name="files"
key="files"
/>
</Form.Group>
}
在父级中,我有一个自定义UploadFile组件的实例,例如:
const [listOfFiles, setListOfFiles] = useState([]);
const handleFilesChange = (e) {
setListOfFiles(e.target.files);
}
<UploadFile
handleFilesChange = { e => handleFilesChange(e) }
files = {listOfFiles}
/>
EDIT:如果您想在UploadFile组件中触发console.log
,则必须触发一个重新应答器。目前,我没有看到您在UploadFile组件的渲染方法中使用props.files
。也许试试这个:
const UploadFile = (props) => {
// stuff here
console.log(props.files);
const randomClassName = `random-class-name-${props.files.length}`;
return {
<Form.Group controlId="formFileMultiple" className="mb-3">
<Form.Label className={randomClassName}> Files </Form.Label>
<Form.Control
type="file" multiple
onChange={props.handleFilesChange}
name="files"
key="files"
/>
</Form.Group>
}
}
但正确的方法是使用useEffect
钩子,每当变量独立于渲染方法发生变化时,就会触发它。这里有一个例子:
import { useEffect } from "react";
const UploadFile = (props) => {
useEffect(() => {
// stuff here
console.log(props.files);
}, [props.files]);
return {
<Form.Group controlId="formFileMultiple" className="mb-3">
<Form.Label> Files </Form.Label>
<Form.Control
type="file" multiple
onChange={props.handleFilesChange}
name="files"
key="files"
/>
</Form.Group>
}
}
FileList
,也没有在子组件中看到这些道具的更改。如果您将FileList
转换为array
,它将完美工作。
const UploadFile = (props) => {
// stuff here
console.log(props.files);
return <ReactBootstrap.Form.Group controlId="formFileMultiple" className="mb-3">
<ReactBootstrap.Form.Label> Files </ReactBootstrap.Form.Label>
<ReactBootstrap.Form.Control
type="file" multiple
onChange={props.handleFilesChange}
name="files"
key="files"
/>
</ReactBootstrap.Form.Group>
}
function App() {
const [listOfFiles, setListOfFiles] = React.useState([]);
const handleFilesChange = (e) => {
setListOfFiles(Array.from(e.target.files));
}
return <UploadFile
handleFilesChange = { e => handleFilesChange(e) }
files = {listOfFiles}
/>
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
<script src="https://unpkg.com/react/umd/react.production.min.js" crossorigin></script>
<script
src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"
crossorigin></script>
<script
src="https://unpkg.com/react-bootstrap@next/dist/react-bootstrap.min.js"
crossorigin></script>
<div id="root"></div>
澄清:
FileList不受react管理,因为它的值只能由用户设置,而不能以编程方式设置:https://reactjs.org/docs/uncontrolled-components.html#the-文件输入标签