ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

javascript-在useEffect中将componentDidUpdate代码与DidMount和UnMount一起使用

2019-12-11 05:33:32  阅读:340  来源: 互联网

标签:reactjs react-hooks javascript


我正在尝试将我的代码迁移到支持react挂钩的新react上.我正在使用useReducer,useState和useEffect.我可以在代码中使用DidMount和UnMount,但对如何实现DidUpdate部分一无所知,因为这可能会导致重新渲染问题.

这是我做的

旧代码

class ImageBoard extends React.Component {
    constructor() {
      super();
      this.state = {
        canvas: undefined,
        selected: undefined
      };
    }

    handleDeleteKey(event) {
      if (event.keyCode === 46 || event.keyCode === 8) {
        event.preventDefault();
        if (this.state.selected !== undefined) {
          this.state.canvas.remove(this.state.selected);
          this.setState({ selected: undefined });
        }
      }
    }

    componentDidMount() {
      const canvas = new fabric.Canvas("canvas");
      document.addEventListener("keydown",this.handleDeleteKey.bind(this),false);
      canvas.on("object:selected", e => this.setState({ selected: e.target }));
      canvas.on("selection:cleared", e => this.setState({ selected: undefined }));
      this.setState({ canvas: canvas });
      this.setCanvasBackground(this.props.getSelectedImage, canvas);
    }

    componentDidUpdate(prevProps) {
      if (prevProps.getSelectedImage !== this.props.getSelectedImage) {
        this.setCanvasBackground(this.props.getSelectedImage,this.state.canvas);
      }

    }

更改为以下新代码

const ImageBoard = () => {
  let canvasEl = React.useRef(null);
  const [selected, setSelected] = React.useState(null)
  const [canvas, setCanvas] = React.useState(null)
 const [state, _] = React.useReducer(imagesReducer, [])

  const handleDeleteKey = event => {
    if (event.keyCode === 46 || event.keyCode === 8) {
      event.preventDefault();
      if (selected !== undefined) {
        canvas.remove(selected);
        setSelected(undefined);
      }
    }
  }

  React.useEffect(() => {
    const canvas = new fabric.Canvas("canvas");
    document.addEventListener(
      "keydown",
      handleDeleteKey,
      false
    );
    canvas.on("object:selected", e => setSelected(e.target));
    canvas.on("selection:cleared", e => setSelected(undefined));
    setCanvas(canvas);
    setCanvasBackground(state.images.selectedImage, canvas);
    return () => {
      document.removeEventListener("keydown", handleDeleteKey, false);
    }
  }, [])

我如何在useEffect中编写以下代码片段?

componentDidUpdate(prevProps) {
          if (prevProps.getSelectedImage !== this.props.getSelectedImage) {
            this.setCanvasBackground(this.props.getSelectedImage,this.state.canvas);
          }
          this.setCanvasBackground(this.props.getSelectedImage,this.state.canvas);
        }

解决方法:

如果目的是避免在接收到相同的道具时发生不必要的更新,并且这不仅适用于getSelectedImage,而且适用于所有道具,则可以使组件纯净:

const ImageBoard = memo(props => { ... });

因此,仅当收到新的道具(包括useEffect)时,才重新渲染组件:

  useEffect(() => {
    // runs every time the component is rendered
    setCanvasBackground(props.getSelectedImage, canvas);
  })

如果仅在收到特定道具的新值​​(例如getSelectedImage)的新值时才评估组件的一部分,则根据情况使用useMemo或useEffect挂钩完成此操作.由于useEffect可以同时充当componentDidUpdate和componentDidMount,因此应将其考虑在内.

  useEffect(() => {
    // runs once on mount
    const canvas = new fabric.Canvas("canvas");
    document.addEventListener(
      "keydown",
      handleDeleteKey,
      false
    );
    canvas.on("object:selected", e => setSelected(e.target));
    canvas.on("selection:cleared", e => setSelected(undefined));
    setCanvas(canvas);
    // setCanvasBackground is moved to another hook
    return () => {
      document.removeEventListener("keydown", handleDeleteKey, false);
    }
  }, [])

  useEffect(() => {
    // runs every time new getSelectedImage is received, including initial render
    setCanvasBackground(props.getSelectedImage, canvas);
  }, [props.getSelectedImage])

标签:reactjs,react-hooks,javascript
来源: https://codeday.me/bug/20191211/2106776.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有