超級(jí)工程網(wǎng)站建設(shè)網(wǎng)站優(yōu)化排名的方法
文章目錄
- render-props 模式
- props 方式
- children 方式(推薦)
- Hoc(高階組件)
- 使用步驟
- 示例
- props 丟失
- 解決方案
- 自定義 hook
- 1.只執(zhí)行一次
- 2.防抖hook
- 高階組件與自定義hook有什么區(qū)別
- 相同點(diǎn)
- 不同點(diǎn)
React 中代碼邏輯復(fù)用有三種方式,render-props
, Hoc
,·自定義hooks·
注意: render-props
, Hoc
這兩種方式不是新的API,而是利用React自身特點(diǎn)的編碼技巧,演化而成的固定模式(寫法)
render-props 模式
注意: 并不是該模式叫 render props 就必須使用名為 render 的 prop,實(shí)際上可以使用任意名稱的 prop
props 方式
封裝一個(gè) render-props 模式下的鼠標(biāo)移動(dòng),得到鼠標(biāo)當(dāng)前移動(dòng)位置
// 封裝的組件
class Mounse extends React.Component {state = {x: 0,y: 0}componentDidMount(){window.addEventListener('mousemove', this.mouseMove)}componentWillUnmount(){window.removeEventListener("mousemove", this.mouseMove)}mouseMove= (e) => {this.setState({x: e.clientX,y: e.clientY}) } render(){renten this.props.render(this.state)}
}// 使用
export default function Index() {return (<h1><Mouns render={(mouse)=>{return <p>x: { mouse.x }----y: { mouse.y }</p>}} /> )
}
children 方式(推薦)
// 封裝的組件
class Mounse extends React.Component {state = {x: 0,y: 0}componentDidMount(){window.addEventListener('mousemove', this.mouseMove)}componentWillUnmount(){window.removeEventListener("mousemove", this.mouseMove)}mouseMove= (e) => {this.setState({x: e.clientX,y: e.clientY}) } render(){renten this.props.children(this.state)}
}
使用
// 使用
export default function Index() {return (<h1><Mouns>{(mouse)=>{<p>x: { mouse.x }----y: { mouse.y }</p>}}</Mouns> )
}
Hoc(高階組件)
高階組件使用一個(gè)函數(shù),接收要包裝的組件,返回一個(gè)增強(qiáng)后的組件
使用步驟
- 創(chuàng)建一個(gè)函數(shù),以
with
開頭 - 指定函數(shù)參數(shù),函數(shù)參數(shù)為一個(gè)組件,組件以大寫字母開頭
- 在函數(shù)內(nèi)創(chuàng)建一個(gè)類組件,提供狀態(tài)邏輯代碼,并返回
示例
function WithMounse(Com) {class Mounse extends PureComponent {state = {x: 0,y: 0}componentDidMount(){window.addEventListener('mousemove',this.handleMonve)}componentWillUnmount(){window.removeEventListener("mousemove", this.handleMonve)}handleMonve = e => { this.setState({x: e.clientX,y: e.clientY})}render(){return <Com {...this.state} />}}return <Mounse />}const Foo = props => { return <p>{props.x}...{props.y}</p>}const EndCom = WithMounse(Foo).type// 調(diào)用class App extends PureComponent {render() {return (<EndCom />)}}
props 丟失
問題示范
由圖片可以看出,在高階組件中傳入一個(gè) props 屬性 a = 1
在組件里面接收不到,這就是屬性丟失
解決方案
在高階組件封裝的時(shí),對props屬性再次進(jìn)行傳遞
示例
<Com {...this.state} {...this.props} />
function WithMounse(Com) {class Mounse extends PureComponent {state = {x: 0,y: 0}componentDidMount(){window.addEventListener('mousemove',this.handleMonve)}componentWillUnmount(){window.removeEventListener("mousemove", this.handleMonve)}handleMonve = e => { this.setState({x: e.clientX,y: e.clientY})}render(){return <Com {...this.state} {...this.props} />}}return <Mounse />}
自定義 hook
hook 是react16.8 的新特性,它可以在你不編寫class組件的情況下使用state一級(jí)其他的React的特性
通過自定義hook,可以將組件邏輯提取到可重復(fù)的函數(shù)中
注意:自定義hook 一定以 use 開頭,例如 useDebonce
,useQuery
等等
下面是幾個(gè)自定義 hook 的封裝
1.只執(zhí)行一次
export const useMount = (callback: () => void) => {useEffect(() => {callback()}, [])
}
使用
useMount(()=>{// 數(shù)據(jù)請求})
2.防抖hook
export const useDebonce = <T>(value: T, delay?: number): T => {const [debounce, setDebounce] = useState(value)useEffect(()=>{let timer = setTimeout(()=>{setDebounce(value)}, delay)return ()=> clearTimeout(timer) },[value, delay])return debounce
}
使用
const changeValue = '改變所依賴的值'const Debonce = useDebonce(changeValue, 300)useEffect(()=>{console.log('changeValue')},[Debonce])
高階組件與自定義hook有什么區(qū)別
相同點(diǎn)
- 都是對組件邏輯的封裝,達(dá)到組件邏輯復(fù)用的目的
不同點(diǎn)
- 定義方式不同:高階組件以
with開頭
,自定義hook以use
開頭 - 特性不同:高階組件是類組件中的總結(jié)出來的一種編碼技巧,自定義hook 是
react16.8
后出來的新特性 - 使用場景不同: 高階組件一般在函數(shù)組件中使用,自定義hook只有函數(shù)組件中有
- 返回值不同:高階組件的返回值是一個(gè)組件,自定義hook的返回值可有可無