reactDOM

前置

react-dom 提供了可在应用顶层使用的 DOM(DOM-specific)方法。

  • render()
  • hydrate()
  • unmountComponentAtNode()
  • findDOMNode()
  • createPortal()

你可以使用以下命令在本地启动一个 node 服务器,运行本文的示例。

npm i create-react-app -g
create-react-app test --typescript --use-npm
npm start

render

render 有三个参数:

  • 要渲染的 React 元素
  • 元素挂载位置
  • 在组件被渲染或更新之后被执行的回调
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root'),
  () => {}
)

渲染机制:

hydrate

与 render() 相同,但它用于在 ReactDOMServer 渲染的容器中对 HTML 的内容进行 hydrate 操作。

unmountedComponentAtNode

从 DOM 中卸载组件,会将其事件处理器(event handlers)和 state 一并清除。如果指定容器上没有对应已挂载的组件,这个函数什么也不会做。如果组件被移除将会返回 true,如果没有组件可被移除将会返回 false。

ReactDOM.unmountComponentAtNode(document.getElementById('root') as HTMLElment)

document.getElementById('root') 可能返回 HTMLElment 或者 null ,ReactDOM.unmountComponentAtNode 不能接收 null,使用 as 强制指定。unmountComponentAtNode 卸载组件会走生命周期函数(卸载)。原生 js 的 remove() 不会走。

findDOMNode

如果组件已经被挂载到 DOM 上,此方法会返回浏览器中相应的原生 DOM 元素。此方法对于从 DOM 中读取值很有用,例如获取表单字段的值或者执行 DOM 检测(performing DOM measurements)。**
大多数情况下,你可以绑定一个 ref 到 DOM 节点上,可以完全避免使用 findDOMNode。**

findDOMNode 不能用于函数组件。

findDOMNode 是一个访问底层 DOM 节点的应急方案(escape hatch)。在大多数情况下,不推荐使用该方法,因为它会破坏组件的抽象结构。严格模式下该方法已弃用。

let app:any

ReactDOM.render(
  <App ref={node=>app=node} />,document.getElementById('root'),
  ()=>{
    console.log(app)
    // 可以调用app组件原型链上的方法
    app.componentWillUnmount()
    // 获取dom元素
    ReactDom.findDOMNode(app)
  }
)

createPortal

创建 portal。Portal 将提供一种将子节点渲染到 DOM 节点中的方式,该节点存在于 DOM 组件的层次结构之外。


export default class Protal extents React.Component {
  public state = {counter: 0}
  increase() {
    this.setState((prevState: any) => ({
      counter: prevState.counter + 1
    }))
  }
  reader(){
    return{
      <div id="father" onClick={this.increase.bind(this)}>
        <div>counter: {this.state.counter}</div>
        <button></button>
      </div>
    }
  }
}
index.html

<div id="root"></div>
<div id="protal"></div>

将 Protal 组件挂载到 root,如何把 button 渲染到 protal?

方式一,通过 render

  reader(){
    ReactDOM.reader(<button>Click</button>. document.getElementById('protal'))
    return{
      <div id="father" onClick={this.increase.bind(this)}>
        <div>counter: {this.state.counter}</div>
        // <button></button>
      </div>
    }
  }

使用 render,事件无法触发

方式二,createPortal

  reader(){
    return{
      <div id="father" onClick={this.increase.bind(this)}>
        <div>counter: {this.state.counter}</div>
        // <button></button>
        {ReactDOM.createPortal(<button></button>,document.getElementById('protal'))}
      </div>
    }
  }

事件正常触发,react 在运行时依然将 button 作为 father 的子元素,这样事件依然可以冒泡触发。

posted @ 2020-07-05 15:06  guangzan  阅读(521)  评论(0编辑  收藏  举报