第二次触发onChange时,自定义组件不会更新



问题: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>
}
}
React不知道如何管理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-文件输入标签

相关内容

  • 没有找到相关文章

最新更新