【问题标题】:React setState is not a function upon adding JSON?React setState 在添加 JSON 时不是一个函数吗?
【发布时间】:2020-10-27 22:51:24
【问题描述】:

我正在尝试使用共享祖先在文件上传器和表之间中继数据。我有一个文件上传器,但是一旦我添加了我的 JSON 文件,我就会收到错误 TypeError: setProductState is not a function。

当我控制台记录我的 inputJson 文件时,它会运行,但是当我应用 setProductState 并输入我的文件时,我会收到此错误。

根据我阅读的内容,我不需要绑定,因为我使用的是箭头语法,但我可能需要一个“this”。

欢迎任何想法或批评。

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;

【问题讨论】:

  • 您可以从检查 setProductState 到底是什么开始。如果它不是一个函数或者它的 undefined,检查你是否正确传递了 props。
  • 显示父组件的代码。 SetProductState 是在哪里定义的?
  • @Benjamin 我已经添加了父组件。它在祖先中定义。谢谢两位的建议。

标签: reactjs callback setstate


【解决方案1】:

我相信您可能对this 关键字的工作原理感到困惑。在您的 FileUploader 组件中,this 将是对 FileUploader 的引用,而不是对祖先的引用。

您不需要对 Ancestor 的引用,因为您将 productssetProducts 作为道具传递。这是正确的做法。

另外,您可能并不是要对接受的文件执行 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>
  );
}

【讨论】:

  • 感谢您的反馈。是的,我将加载一个文件。不幸的是,这个 sn-p 记录 Unhandled Rejection (TypeError): acceptedFiles.item 不是一个函数。我将不得不做进一步的调试。
  • @AlyHoop 我已经更新了代码 sn-p。我错误地认为接受文件是 FileList 的一个实例。 developer.mozilla.org/en-US/docs/Web/API/FileList
  • 在那个版本中,它现在正在记录 TypeError: setProductState is not a function。我会回到道具上。
  • @AlyHoop 我对代码 sn-p 进行了另一项更改,将解构的 props 替换为 props 参数,从而更清楚 setProductState 的来源。
  • 该编辑记录 TypeError: props.setProductState is not a function.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-04
  • 2022-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多