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

前端之家收集整理的这篇文章主要介绍了javascript-在useEffect中将componentDidUpdate代码与DidMount和UnMount一起使用 前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

这是我做的

代码

  1. class ImageBoard extends React.Component {
  2. constructor() {
  3. super();
  4. this.state = {
  5. canvas: undefined,selected: undefined
  6. };
  7. }
  8. handleDeleteKey(event) {
  9. if (event.keyCode === 46 || event.keyCode === 8) {
  10. event.preventDefault();
  11. if (this.state.selected !== undefined) {
  12. this.state.canvas.remove(this.state.selected);
  13. this.setState({ selected: undefined });
  14. }
  15. }
  16. }
  17. componentDidMount() {
  18. const canvas = new fabric.Canvas("canvas");
  19. document.addEventListener("keydown",this.handleDeleteKey.bind(this),false);
  20. canvas.on("object:selected",e => this.setState({ selected: e.target }));
  21. canvas.on("selection:cleared",e => this.setState({ selected: undefined }));
  22. this.setState({ canvas: canvas });
  23. this.setCanvasBackground(this.props.getSelectedImage,canvas);
  24. }
  25. componentDidUpdate(prevProps) {
  26. if (prevProps.getSelectedImage !== this.props.getSelectedImage) {
  27. this.setCanvasBackground(this.props.getSelectedImage,this.state.canvas);
  28. }
  29. }

更改为以下新代码

  1. const ImageBoard = () => {
  2. let canvasEl = React.useRef(null);
  3. const [selected,setSelected] = React.useState(null)
  4. const [canvas,setCanvas] = React.useState(null)
  5. const [state,_] = React.useReducer(imagesReducer,[])
  6. const handleDeleteKey = event => {
  7. if (event.keyCode === 46 || event.keyCode === 8) {
  8. event.preventDefault();
  9. if (selected !== undefined) {
  10. canvas.remove(selected);
  11. setSelected(undefined);
  12. }
  13. }
  14. }
  15. React.useEffect(() => {
  16. const canvas = new fabric.Canvas("canvas");
  17. document.addEventListener(
  18. "keydown",handleDeleteKey,false
  19. );
  20. canvas.on("object:selected",e => setSelected(e.target));
  21. canvas.on("selection:cleared",e => setSelected(undefined));
  22. setCanvas(canvas);
  23. setCanvasBackground(state.images.selectedImage,canvas);
  24. return () => {
  25. document.removeEventListener("keydown",false);
  26. }
  27. },[])

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

  1. componentDidUpdate(prevProps) {
  2. if (prevProps.getSelectedImage !== this.props.getSelectedImage) {
  3. this.setCanvasBackground(this.props.getSelectedImage,this.state.canvas);
  4. }
  5. this.setCanvasBackground(this.props.getSelectedImage,this.state.canvas);
  6. }
最佳答案
如果目的是避免在接收到相同的道具时发生不必要的更新,并且这不仅适用于getSelectedImage,而且适用于所有道具,则可以使组件纯净:

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

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

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

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

  1. useEffect(() => {
  2. // runs once on mount
  3. const canvas = new fabric.Canvas("canvas");
  4. document.addEventListener(
  5. "keydown",e => setSelected(undefined));
  6. setCanvas(canvas);
  7. // setCanvasBackground is moved to another hook
  8. return () => {
  9. document.removeEventListener("keydown",[])
  10. useEffect(() => {
  11. // runs every time new getSelectedImage is received,including initial render
  12. setCanvasBackground(props.getSelectedImage,canvas);
  13. },[props.getSelectedImage])

猜你在找的JavaScript相关文章