React setState 不是添加 JSON 后的函数?
React setState is not a function upon adding JSON?
我正在尝试使用共享祖先在文件上传器和 table 之间中继数据。我有一个文件上传器,但是一旦我添加了 JSON 文件,我就会收到错误 TypeError: setProductState is not a function.
当我控制台记录我的 inputJson 文件时,它会运行,但是当我应用 setProductState 并输入我的文件时,我收到此错误。
根据我读过的内容,我不需要绑定,因为我使用的是箭头语法,但我可能需要 'this'.
- How to access the correct `this` inside a callback?
欢迎提出任何想法或批评。
function FileUploader({ productState, setProductState }) {
const onDrop = useCallback((acceptedFiles) => {
// this.setProductState = this.setProductState.bind(this); tried
acceptedFiles.forEach((file) => {
const reader = new FileReader()
reader.onload = () => {
const inputJson =
this.inputJson = inputJson //tried
JSON.parse(reader.result)
setProductState(inputJson); //console.log goes through
}
reader.readAsText(file)
})
}, [])
const {getRootProps, getInputProps} = useDropzone({onDrop})
return (
<div {...getRootProps({style})}>
<input {...getInputProps()} value={productState}/>
<p>Drag files here, or click to browse</p>
</div>
)
}
Ancestor.js
import React, { useState } from 'react'
import FileUploader from './FileUploader'
import Table from './Table'
const Ancestor = () => {
const [products, setProducts] = useState({});
return <>
<FileUploader productState={products} setProductState={setProducts} />
<Table productState={products} />
</>;
}
export default Ancestor;
我相信您可能对 this
关键字的工作原理感到困惑。在您的 FileUploader 组件中,this
将是对 FileUploader 的引用,而不是对 Ancestor 的引用。
您不需要对 Ancestor 的引用,因为您将 products
和 setProducts
作为道具传递。这才是正确的做法。
此外,您可能并不打算对 acceptedFiles 执行 forEach,因为看起来您只需要一个文件,对吗?
试试这个。
function FileUploader(props) {
// Define an onDrop function to handle drop events
const onDrop = useCallback((acceptedFiles) => {
// Get the first file in the list of acceptedFiles
const file = acceptedFiles[0];
// Create a FileReader
const reader = new FileReader();
// Create a function to handle the reader onload event
reader.onload = () => {
// JSON parse the result from read as text
let parsed = JSON.parse(reader.result);
// Call the setProductState function from Ancestor component
props.setProductState(parsed);
};
// Read the file, triggering the onload event handler
reader.readAsText(file);
}, []);
const { getRootProps, getInputProps } = useDropzone({ onDrop });
return (
<div {...getRootProps({ style })}>
<input {...getInputProps()} value={props.productState} />
<p>Drag files here, or click to browse</p>
</div>
);
}
我正在尝试使用共享祖先在文件上传器和 table 之间中继数据。我有一个文件上传器,但是一旦我添加了 JSON 文件,我就会收到错误 TypeError: setProductState is not a function.
当我控制台记录我的 inputJson 文件时,它会运行,但是当我应用 setProductState 并输入我的文件时,我收到此错误。
根据我读过的内容,我不需要绑定,因为我使用的是箭头语法,但我可能需要 'this'.
- How to access the correct `this` inside a callback?
欢迎提出任何想法或批评。
function FileUploader({ productState, setProductState }) {
const onDrop = useCallback((acceptedFiles) => {
// this.setProductState = this.setProductState.bind(this); tried
acceptedFiles.forEach((file) => {
const reader = new FileReader()
reader.onload = () => {
const inputJson =
this.inputJson = inputJson //tried
JSON.parse(reader.result)
setProductState(inputJson); //console.log goes through
}
reader.readAsText(file)
})
}, [])
const {getRootProps, getInputProps} = useDropzone({onDrop})
return (
<div {...getRootProps({style})}>
<input {...getInputProps()} value={productState}/>
<p>Drag files here, or click to browse</p>
</div>
)
}
Ancestor.js
import React, { useState } from 'react'
import FileUploader from './FileUploader'
import Table from './Table'
const Ancestor = () => {
const [products, setProducts] = useState({});
return <>
<FileUploader productState={products} setProductState={setProducts} />
<Table productState={products} />
</>;
}
export default Ancestor;
我相信您可能对 this
关键字的工作原理感到困惑。在您的 FileUploader 组件中,this
将是对 FileUploader 的引用,而不是对 Ancestor 的引用。
您不需要对 Ancestor 的引用,因为您将 products
和 setProducts
作为道具传递。这才是正确的做法。
此外,您可能并不打算对 acceptedFiles 执行 forEach,因为看起来您只需要一个文件,对吗?
试试这个。
function FileUploader(props) {
// Define an onDrop function to handle drop events
const onDrop = useCallback((acceptedFiles) => {
// Get the first file in the list of acceptedFiles
const file = acceptedFiles[0];
// Create a FileReader
const reader = new FileReader();
// Create a function to handle the reader onload event
reader.onload = () => {
// JSON parse the result from read as text
let parsed = JSON.parse(reader.result);
// Call the setProductState function from Ancestor component
props.setProductState(parsed);
};
// Read the file, triggering the onload event handler
reader.readAsText(file);
}, []);
const { getRootProps, getInputProps } = useDropzone({ onDrop });
return (
<div {...getRootProps({ style })}>
<input {...getInputProps()} value={props.productState} />
<p>Drag files here, or click to browse</p>
</div>
);
}