前置
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'),
() => {}
)
渲染機制:
- stack https://claudiopro.github.io/react-fiber-vs-stack-demo/stack.html
先比對再更新視圖 - fiber https://claudiopro.github.io/react-fiber-vs-stack-demo/fiber.html
將比對拆分
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 的子元素,這樣事件依然可以冒泡觸發,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/45591.html
標籤:JavaScript
上一篇:Algolia Search
