繁体   English   中英

将 React Class 组件转换为 React 函数式组件

[英]Converting React Class Component to a React Functional Component

我正在尝试转换一个 React Class 组件,但在一天的尝试失败后失败了。

当前的 class 组件如下所示:

class NeonCursor extends React.Component {
  constructor(props) {
    super(props);

    this.state = { top: 0, left: 0 };
  }

  componentDidMount() {
    document.addEventListener('mousemove', handleMouseMove);
    document.documentElement.classList.add('no-cursor');
  }

  componentWillUnmount() {
    document.documentElement.classList.remove('no-cursor');
    document.removeEventListener('mousemove', handleMouseMove);
  }

  handleMouseMove = (e) => {
    this.setState({
      top: e.pageY,
      left: e.pageX,
    });
  };

  render() {
    return (
      <img
        src="https://code.s3.yandex.net/web-code/react/cursor.svg"
        width={30}
        style={{
          position: 'absolute',
          top: this.state.top,
          left: this.state.left,
          pointerEvents: 'none',
        }}
      />
    );
  }
}

我目前的尝试是这样的:

function NeonCursor(props) {
  
  const [top, setTop] = React.useState(top: 0);
  const [left, setLeft] = React.useState(left: 0);
  
  React.useEffect(() => {
    document.addEventListener('mousemove', handleMouseMove);
    document.documentElement.classList.add('no-cursor');
    
    return () => {
      document.documentElement.classList.remove('no-cursor');
    document.removeEventListener('mousemove', handleMouseMove);
    }
  }); 
  
  return (
      <img
        src="https://code.s3.yandex.net/web-code/react/cursor.svg"
        width={30}
        style={{
          position: 'absolute',
          top: setTop,
          left: setLeft,
          pointerEvents: 'none',
        }}
      />
    );
  
  function handleMouseMove = (e) => {
    setState({
      setTop: e.pageY,
      setLeft: e.pageX,
    });
  };
  
}

到目前为止,我已经完成了以下步骤:

  1. 使用 function() 命名重命名 class 组件
  2. 删除 class 构造函数
  3. 使用useState钩子替换构造函数中的state
  4. 通过回调将 ComponentDidMount 和 ComponentWillUnmount 方法传递给 React.useEffect 挂钩。
  5. 换掉这一切this. 来自代码的语法。
  6. 将 handleMouseMove 方法转换为 function。

但是我的代码不工作,总是出现“脚本错误”。 信息。

这种转换的正确方法是什么?

我准备了codepens: 原始代码: https://codepen.io/aegisnull/pen/YzLaxQJ我的尝试: https://codepen.io/aegisnull/pen/xxjWLXp

首先,您以错误的方式定义了 useState 挂钩。

const [top, setTop] = React.useState(top: 0);
const [left, setLeft] = React.useState(left: 0);

它应该是:

const [top, setTop] = React.useState(0); // 0 is initial/default value of state called top
const [left, setLeft] = React.useState(0);

其次,您的处理程序也有错误

function handleMouseMove = (e) => {
    setState({
      setTop: e.pageY,
      setLeft: e.pageX,
    });
};

react fc 组件没有setState这就是为什么在 react 有一个钩子之前它被称为无状态组件。 当您定义 state [top, setTop]时, setTop为 function 以更新top的值。 所以你的handleMouseMove应该是:

function handleMouseMove = (e) => {
    setTop(e.pageY)
    setLeft(e.pageX)
};

主要问题是您对 state 的使用以及 handleMouseMove function 和 handleMouseMove function 声明的位置。

您的 state 变量称为 top 和 left ,这些是您在使用该值时所指的(根据图像中的样式标签)。 您使用它们的关联集 function 更新它们,即 setTop 用于更新顶部或 setLeft 用于更新左侧(如 handleMouseMove 函数所示)。 它们的初始值定义在括号中。 由于这些是为了存储 x 或 y 坐标,因此它们都是数字类型。

handleMouseMove function 需要移动到 return 语句上方以保留在 scope 中并且声明固定。

尝试这个

function NeonCursor(props) {

    const [top, setTop] = React.useState(0);
  const [left, setLeft] = React.useState(0);
  
  React.useEffect(() => {
    document.addEventListener('mousemove', handleMouseMove);
    document.documentElement.classList.add('no-cursor');
    
    return () => {
      document.documentElement.classList.remove('no-cursor');
    document.removeEventListener('mousemove', handleMouseMove);
    }
  }); 

  const handleMouseMove = (e: any) => {
    console.log(e)
    setTop(e.pageY)
    setLeft(e.pageX)
  };
  
  return (
      <img
        src="https://code.s3.yandex.net/web-code/react/cursor.svg"
        alt="cursor"
        width={30}
        style={{
          position: 'absolute',
          top: top,
          left: left,
          pointerEvents: 'none',
        }}
      />
    );
  
  
}

export default NeonCursor;

暂无
暂无

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

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