反应条件组件渲染

问题描述

我目前正在尝试创建一个 React 组件来使用 croppie上传和裁剪图像。

我找到了这个代码示例

import "croppie/croppie.css"
import { Button,Grid } from "@material-ui/core"
import * as React from "react"
import croppie from "croppie"

export function croppieExample() {
  const [image,setimage] = React.useState("")
  const [croppie,setcroppie] = React.useState<croppie | null>(null)

  function handleImage(image: string) {
    setimage(image)
    const el = document.getElementById("image-helper")
    if (el) {
      const croppieInstance = new croppie(el,{
        enableExif: true,viewport: {
          height: 250,width: 250,},boundary: {
          height: 280,width: 400,}
    });
    croppieInstance.bind({
      url: image,});
    setcroppie(croppieInstance)
    }
  }

  function handleSubmit(event: any) {
    event.preventDefault()
    if (croppie !== null) {
      croppie.result({type: 'base64',size: {
          width: 480,height: 480
      }}).then((blob) => {
        console.log(blob)
      }
      )
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <Grid container spacing={2}>
        {image === "" && (
            <Grid item xs={12}>
                {/* Your image upload functionality here */}
                <ImageUpload image={image} setimage={handleImage} />
            </Grid>
            )}
        {image !== "" && (
            <Grid item container justify="center" xs={12}>
              <div id="image-helper"></div>
            </Grid>
            )}
        <Grid container item xs={12} justify="flex-end">
          <Button color="primary" variant="contained" type="submit">
            Submit
          </Button>
        </Grid>
      </Grid>
    </form>
  )
}

我有一个关于这段代码的条件部分的问题:

为了工作,必须将 croppie 实例附加到 div 元素“image-helper”。 handleImage 事件负责croppieInstance的创建。但是当它被调用时,它似乎没有被渲染,所以无法创建croppie 实例。

我的假设正确吗?

如果是这样,React 纠正代码方法是什么?

感谢您的帮助

解决方法

是的,你的分析是对的。代码片段令人震惊。当 DOM 元素最终可用时,React 中初始化任何代码的正确方法是通过回调引用。

const initImageHelper = useCallback(
  (element) => {
    if (element) {
      const croppieInstance = new Croppie(element,settings);
      croppieInstance.bind({ url: image });
      setCroppie(croppieInstance);
    }
  },[image]
);


          {image !== "" && (
            <Grid item container justify="center" xs={12}>
              <div id="image-helper" ref={initImageHelper}></div>
            </Grid>
          )}