繁体   English   中英

React Hooks:在钩子组件的子级之间传递 state 的最佳实践

[英]React Hooks: Best practise in passing state between children of hook component

我想访问设置为子组件 state 的 object,并将其传递给其兄弟组件:

  • Child 1 (TextDetection) 是一个接收图像文件的react-dropzone 组件,该文件被传递给 OCR API。
  • 然后子 1 将从 API 接收转录,并将返回的转录设置为其本地 state。
  • Child 2 (TextTable) 需要访问同样的 object,它将在其中显示。

孩子 1

function TextDetection({ textToParent }) {
  const [data, setData] = useState([])

  const uploadImage = async (image) => {
    var formData = new FormData();
    formData.append('photo', image[0])
    const response = await fetch('/upload', {
      method: "post",
      body: formData
    })
    const body = await response.json();
    setData(body.split(/\r?\n/))
    textToParent(data)
  }

  return (
    <Grid container className="App" direction="column" alignItems="stretch">
      <Container id="dropzoneContainer">
        <Card variant="outlined">
          <Dropzone uploadImage = {uploadImage}/>
        </Card>
      </Container>
    </Grid>
  );
}

目的是使该转录可用于兄弟组件。 正如您在下面的代码片段中看到的,我目前正在通过 props 将回调传递给孩子的 state 来访问它。

家长

export default function App() {
  const [text, setText] = useState([])

  function handleChange(newText) {
    setText(newText)
  }
  
  return (
    <div>
      <Grid item xs={12} sm={4}>
        <TextDetection textToParent={handleChange}/>
      </Grid>
      <Grid item xs={12} sm={8}>
        <TextTable segments={text}/>
      </Grid>
    </div>
  );
}

将回调传递给孩子以访问其 state 与Lifting State Up的概念不一致。 鉴于 TextDetection 子节点接收到设置为 state 的 object,是否有在这种情况下应用该原则的方法?

在您的示例中,您根本不使用 Child 组件中的data 在这种情况下,您可以在父组件中运行 function

function TextDetection({ textToParent }) {
  return (
    <Grid container className="App" direction="column" alignItems="stretch">
      <Container id="dropzoneContainer">
        <Card variant="outlined">
          <Dropzone uploadImage = {textToParent}/>
        </Card>
      </Container>
    </Grid>
  );
}

家长:

export default function App() {
  const [text, setText] = useState([])

  function handleChange(newText) {
     var formData = new FormData();
     formData.append('photo', image[0])
     const response = await fetch('/upload', {
        method: "post",
        body: formData
     })
     const body = await response.json();
     setText(body.split(/\r?\n/))
  }
  
  return (
    <div>
      <Grid item xs={12} sm={4}>
        <TextDetection textToParent={handleChange}/>
      </Grid>
      <Grid item xs={12} sm={8}>
        <TextTable segments={text}/>
      </Grid>
    </div>
  );
}

注意:这是概念,未经测试。

TextDetection组件应处理与 OCR 相关的所有内容,包括解析文本。 但是,它不应该有本地 state。 完成解析后,它应该调用textToParent

function TextDetection({ textToParent }) {
  const uploadImage = async (image) => {
    var formData = new FormData();
    formData.append('photo', image[0])
    const response = await fetch('/upload', {
      method: "post",
      body: formData
    })
    const body = await response.json();
    textToParent(body.split(/\r?\n/));
  }

  return (
    <Grid container className="App" direction="column" alignItems="stretch">
      <Container id="dropzoneContainer">
        <Card variant="outlined">
          <Dropzone uploadImage = {uploadImage}/>
        </Card>
      </Container>
    </Grid>
  );
}

父级应持有由 TextDetection 创建的TextDetection, and supply it to the TextTable`(以及任何其他需要它的子级)。

export default function App() {
  const [text, setText] = useState([])
  
  return (
    <div>
      <Grid item xs={12} sm={4}>
        <TextDetection textToParent={setText}/>
      </Grid>
      <Grid item xs={12} sm={8}>
        <TextTable segments={text}/>
      </Grid>
    </div>
  );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM