Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support React Strict Mode #374

Open
Tracked by #717
jaywcjlove opened this issue Jun 13, 2021 · 5 comments
Open
Tracked by #717

Support React Strict Mode #374

jaywcjlove opened this issue Jun 13, 2021 · 5 comments
Assignees
Projects

Comments

@jaywcjlove
Copy link
Member

jaywcjlove commented Jun 13, 2021

StrictMode 是一个用来突出显示应用程序中潜在问题的工具。与 Fragment 一样,StrictMode 不会渲染任何可见的 UI。它为其后代元素触发额外的检查和警告。

⚠️ 严格模式检查仅在开发模式下运行;它们不会影响生产构建。

你可以为应用程序的任何部分启用严格模式。例如:

import React from 'react';

function ExampleApplication() {
  return (
    <div>
      <Header />
      <React.StrictMode>
        <div>
          <ComponentOne />
          <ComponentTwo />
        </div>
      </React.StrictMode>
      <Footer />
    </div>
  );
}

StrictMode 目前有助于:

  • 识别不安全的生命周期
  • 关于使用过时字符串 ref API 的警告
  • 关于使用废弃的 findDOMNode 方法的警告
  • 检测意外的副作用
  • 检测过时的 context API

过时 API:String 类型的 Refs

如果你之前使用过 React,你可能了解过之前的 API 中的 string 类型的 ref 属性,例如 "textInput"。你可以通过 this.refs.textInput 来访问 DOM 节点。我们不建议使用它,因为 string 类型的 refs 存在 一些问题。它已过时并可能会在未来的版本被移除。

关于使用废弃的 findDOMNode 方法的警告

findDOMNode 也可用于 class 组件,但它违反了抽象原则,它使得父组件需要单独渲染子组件。它会产生重构危险,你不能更改组件的实现细节,因为父组件可能正在访问它的 DOM 节点。findDOMNode 只返回第一个子节点,但是使用 Fragments,组件可以渲染多个 DOM 节点。findDOMNode 是一个只读一次的 API。调用该方法只会返回第一次查询的结果。如果子组件渲染了不同的节点,则无法跟踪此更改。因此,findDOMNode 仅在组件返回单个且不可变的 DOM 节点时才有效。

你可以通过将 ref 传递给自定义组件并使用 ref 转发来将其传递给 DOM 节点。

你也可以在组件中创建一个 DOM 节点的 wrapper,并将 ref 直接绑定到它。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.wrapper = React.createRef();
  }
  render() {
    return <div ref={this.wrapper}>{this.props.children}</div>;
  }
}

检测过时的 context API

过时的 context API 容易出错,将在未来的主要版本中删除。

@jaywcjlove
Copy link
Member Author

const getTarget = () => findDOMNode(triggerRef.current) as HTMLElement;
const getPopupTarget = () => findDOMNode(popupRef.current) as HTMLElement;

@nullptr-z
Copy link
Collaborator

nullptr-z commented Apr 11, 2022

对所有组件添加StrictMode后检查出,还有三个组件中存有潜在问题

@nullptr-z
Copy link
Collaborator

@jaywcjlove Menu组件和Tree组件依赖的动画库react-transition-group中有使用findDOMNode,可能需要等这个库升级,或者寻找其他替代方案

https://github.com/reactjs/react-transition-group/blob/153d57240c05b06e15e37e27ceea618989c2007b/src/Transition.js#L228-L230

@jaywcjlove
Copy link
Member Author

官方说能很好的融合,等待吧。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

No branches or pull requests

2 participants