通過實現(xiàn)一個切換組件我們來深化一下對 React 理解,我們的研究是從一個示例開始,創(chuàng)建一個切換的按鈕來切換部分內(nèi)容顯示和隱藏。
創(chuàng)建一個 button 作為操作切換狀態(tài)的觸發(fā)器。
<button>顯示/隱藏</button>
定義狀態(tài) state,頁面有兩個狀態(tài)分別是
- on:true 顯示內(nèi)容
- on:false 隱藏內(nèi)容
通過更新狀態(tài) state 來更新界面,狀態(tài)更新了會更新 dom 。
state = {
on:false,
}
定義 toggle 方法主要用于負(fù)責(zé)更新 state 中 on 的值來控制頁面狀態(tài),隱藏/顯示界面
toggle = () => {
this.setState({
on:!this.state.on
})
}
簡單實現(xiàn)
{
this.state.on && (
<h1>Zidea</h1>
)
}
import React, { Component } from 'react'
export default class Toggle extends Component {
state = {
on:false,
}
toggle = () => {
this.setState({
on:!this.state.on
})
}
render() {
return (
<div className={toggleStyle}>
{
this.state.on && (
<h1>Zidea</h1>
)
}
<button onClick={this.toggle}>顯示/隱藏</button>
</div>
)
}
}
const toggleStyle = {
background:"blue"
}
我們的控制要顯示或隱藏內(nèi)容是不是一層不變的,為更靈活的考慮,可能控制內(nèi)容根據(jù)不同情況(場景)會有所不同,我們將這部分內(nèi)容作為 children 參數(shù)傳入來提供組件復(fù)用性。
render() {
return (
<div className={toggleStyle}>
{
this.state.on && (
this.props.children
)
}
<button onClick={this.toggle}>顯示/隱藏</button>
</div>
)
}
<div>
<Toggle>
<h1>angular basic tut</h1>
</Toggle>
</div>
Render props
從字面上不難理解為 render 的屬性傳入組件,來控制渲染。
render() {
return (
<div>
<ToggleRenderProps render={()=>(
<div>
<h1>tut list</h1>
<button>隱藏/顯示</button>
</div>
)}/>
</div>
)
}
然后我們通過 props 方法到作為 props 傳入的參數(shù)來使用,可以調(diào)用 render 函數(shù)將界面渲染出來。
render() {
const { render} = this.props;
return (
<div>
{render()}
</div>
)
}
既然 render 函數(shù),是不是可以將參數(shù)參入函數(shù)來使用呢?當(dāng)然沒有問題,我們可以嘗試在組件內(nèi)部來控制組件顯示。
<ToggleRenderProps render={(str)=>(
<div>
<h1>{str}</h1>
<button>隱藏/顯示</button>
</div>
)}/>
這樣就順利將 hello zidea 顯示到我們的界面上了。
render() {
const { render} = this.props;
return (
<div>
{render('hello zidea')}
</div>
)
}
既然可以可以傳參數(shù),那么也可以傳入一個對象進(jìn)入界面。
<div>
{render({
on:this.state.on,
toggle:this.toggle
})}
</div>
這樣我們 render 方法就可以接收到組件內(nèi)部 state 和 toggle 方法來控制行為,這樣就將功能和界面成功進(jìn)行分離來實現(xiàn)更靈活的效果。
render() {
return (
<div>
<ToggleRenderProps render={({on, toggle})=>(
<div>
{
on && <h1>Hey zidea</h1>
}
<button onClick={toggle}>隱藏/顯示</button>
</div>
)}/>
</div>
)
}
其實這里 render 我們給其任意名稱,render 只是一個名稱而已,既然這樣我們可以可以用 children ,children 使我們的固有函數(shù)
render() {
const { children } = this.props;
return children({
on:this.state.on,
toggle:this.toggle
})
}
render() {
return (
<div>
<ToggleRenderRPC>
{ ({on,toggle}) => (
<div>
{on && <h1>Zidea React</h1>}
<button onClick={toggle}>顯示/隱藏</button>
</div>
)}
</ToggleRenderRPC>
</div>
)
}
import React, { Component,Fragment } from 'react'
在 react 新特性中提供 Fragment 。
render() {
return (
<div>
<ToggleRenderRPC>
{ ({on,toggle}) => (
<Fragment>
{on && <h1>Zidea React</h1>}
<button onClick={toggle}>顯示/隱藏</button>
</Fragment>
)}
</ToggleRenderRPC>
</div>
)
}