关于前端:函数式组件与类组件有何不同

43次阅读

共计 2495 个字符,预计需要花费 7 分钟才能阅读完成。

前言

React 中最要害的知识点就是 组件 ,在 React 16.8 之前(还没有 Hooks 前),咱们的利用大多写成 Class 组件,因为 Class 组件有生命周期,能管制状态(state)。但函数式组件只能默默站在前面,说本人是木偶组件(也叫无状态组件),传来 props,展现 UI

以下文字都基于有了 Hooks 后

注释

函数式组件和类组件之间是否有什么基本上的区别?

函数式组件捕捉渲染时的值

具体能够看这篇文章:函数式组件与类组件有何不同?

因为在 React 中 props 是不可变(immutable)的,它们永远不会扭转。然而,this 是可变(mutable)的

事实上,这就是类组件 this 存在的意义。React 自身会随着工夫的推移而扭转,以便你能够在渲染办法以及生命周期办法中失去最新的实例

函数式组件会捕捉以后状态下的值,如果你应用定时器扭转以后值的状态,那函数式组件显示的还是原来的值,而不是最新值。而类组件会始终获取最新值

只有一渲染,函数式组件就会捕捉以后的值。而类组件即便渲染了,然而它的 this 会指向最新的实例

类组件

能够看线上 Demo

class ClassDemo extends React.Component {
  state = {value: ""};

  showMessage = () => {alert("最新值为" + this.state.value);
  };

  handleMessageChange = (e) => {this.setState({ value: e.target.value});
  };

  handleClick = () => {setTimeout(this.showMessage, 3000);
  };

  render() {
    return (
      <div>
        <input value={this.state.value} onChange={this.handleMessageChange} />
        <button onClick={this.handleClick}> 点击 </button>
      </div>
    );
  }
}

这样的后果是点击后获取到最新的值,而不是 3 秒前的值。为什么?因为 this 可变,3 秒之后执行 alert("最新值为" + this.state.value)。this.state.value 指向最新的值

如果类组件如果想保留原来的值该怎么做?

一、调用事件之前读取 this.props

能够看线上 Demo

showMessage = (value) => {alert("最新值为" + value);
};

handleClick = () => {const { value} = this.state;
    setTimeout(() => this.showMessage(value), 3000);
};

能够解决,但点击时获取到以后的 user,再传递给 this.showMessage,这样,即便 3 秒之后也是原来的值

毛病:每次都要从 this.props 中拿值,如果数据一多,写起来不合乎兽性

二、在构造函数中绑定办法

能够看线上 Demo

constructor(props) {super(props);
    this.showMessage = this.showMessage.bind(this);
    this.handleClick = this.handleClick.bind(this);
}

这个办法解决不了问题。咱们的问题是咱们从 this.props 中读取数据太迟了—— 读取时曾经不是咱们所须要应用的上下文

三、利用闭包

把办法写进 render 中,这样每次渲染时就能捕捉住过后所用的 props 或者 state

能够看线上 Demo

class ClassDemo extends React.Component {
  state = {value: ""};

  render() {const { value} = this.state;

    const showMessage = () => {alert("最新值为" + value);
    };

    const handleMessageChange = (e) => {this.setState({ value: e.target.value});
    };

    const handleClick = () => {setTimeout(showMessage, 3000);
    };
    return (
      <div>
        <input value={this.state.value} onChange={handleMessageChange} />
        <button onClick={handleClick}> 点击 </button>
      </div>
    );
  }
}

然而这个办法很蠢,这个写法和函数式组件有什么区别呢?还不如用函数式组件呢

函数式组件如果想保留最新的值呢

应用 useRef 保留最新的值,让组件取得最新的值

function MyComponent() {const ref = useRef(null);
}

首先,ref 与实例都表演同样的角色,ref 对象是一个有 current 属性的一个容器

上次的例子咱们用函数式组件就能够这样写:

const FunctionDemo = () => {const [value, setValue] = useState("");

  const refValue = useRef("");

  const showMessage = () => {alert("最新值为" + refValue.current);
  };

  const handleMessageChange = (e) => {setValue(e.target.value);
    refValue.current = e.target.value;
  };

  const handleClick = () => {setTimeout(showMessage, 3000);
  };

  return (
    <div>
      <input value={value} onChange={handleMessageChange} />
      <button onClick={handleClick}> 点击 </button>
    </div>
  );
};

能够看线上 Demo

这里笔者提出两个疑难:

  • 为什么 ref 能保留住最新的值?
  • 为什么函数式组件会捕捉,类组件不会呢?

后续文章会给出笔者的答复

参考资料

  • 函数式组件与类组件有何不同?

正文完
 0