React父組件調(diào)用子組件中的方法實(shí)例詳解
文章中涉及 ref 的應(yīng)用僅為父組件調(diào)用子組件場景下的應(yīng)用方式,并未涵蓋 ref 的所有應(yīng)用方式!
Class組件
1. 自定義事件
Parent.js
import React, { Component } from 'react';
import Child from './Child';
class Parent extends Component {
componentDidMount () {
console.log(this.childRef)
}
handleChildEvent = (ref) => {
// 將子組件的實(shí)例存到 this.childRef 中, 這樣整個(gè)父組件就能拿到
this.childRef = ref
}
//按鈕事件處理
handleClick = () => {
// 通過子組件的實(shí)例調(diào)用組組件中的方法
this.childRef.sendMessage()
}
render () {
return (
<>
<Child
onChildEvent={this.handleChildEvent}
/>
<button onClick={this.handleClick}>Trigger Child Event</button>
</>
);
}
}
export default Parent;Child.js
import React, { Component } from 'react';
class Child extends Component {
//子組件完成掛載時(shí), 將子組件的方法 this 作為參數(shù)傳到父組件的函數(shù)中
componentDidMount () {
// 在子組件中調(diào)用父組件的方法,并把當(dāng)前的實(shí)例傳進(jìn)去
this.props.onChildEvent(this)
}
// 子組件的方法, 在父組件中觸發(fā)
sendMessage = () => {
console.log('sending message')
}
render () {
return ( <div>Child</div> );
}
}
export default Child;
2. 使用 React.createRef()
ParentCmp.js
import React, { Component } from 'react';
import ChildCmp from './ChildCmp';
export default class ParentCmp extends Component {
constructor(props) {
super(props)
// 創(chuàng)建Ref
this.childRef = React.createRef()
}
// 按鈕事件
handleClick = () => {
// 直接通過 this.childRef.current 拿到子組件實(shí)例
this.childRef.current.sendMessage()
}
render () {
return (
<>
<ChildCmp ref={this.childRef} />
<button onClick={this.handleClick}>Trigger Child Event</button>
</>
);
}
}
而子組件就是一個(gè)普通的組件
ChildCmp.js
import React, { Component } from 'react';
export default class ChildCmp extends Component {
sendMessage = () => {
console.log('sending message')
}
render () {
return 'Child';
}
}
3. 使用回調(diào)Refs
回調(diào) Refs 是另一種設(shè)置 Ref 的方式,它能助你更精細(xì)地控制何時(shí) refs 被設(shè)置和解除。
不同于傳遞 createRef() 創(chuàng)建的 ref 屬性,需要傳遞一個(gè)函數(shù)。
訪問 Ref 的時(shí)候也不需要 current。
ParentCmp.js
import React, { Component } from 'react';
import ChildCmp from './ChildCmp';
export default class ParentCmp extends Component {
constructor(props) {
super(props)
// 創(chuàng)建 Ref,不通過 React.createRef()
this.childRef = null
}
// 設(shè)置 Ref
setChildRef = (ref) => {
this.childRef = ref
}
// 按鈕事件
handleClick = () => {
// 直接通過 this.childRef 拿到子組件實(shí)例
this.childRef.sendMessage(`Trigger Child Event from Parent`)
}
render () {
return (
<>
<ChildCmp ref={this.setChildRef} />
<button onClick={this.handleClick}>Trigger Child Event</button>
</>
);
}
}
而子組件還是一個(gè)普通的組件
ChildCmp.js
import { Component } from 'react';
export default class ChildCmp extends Component {
sendMessage = (message) => {
console.log('sending message:', message)
}
render () {
return 'Child';
}
}
【注】對(duì)比自定義事件方式,回調(diào) Refs 更像是精簡的自定義事件方式:
- 自定義事件名稱變成了 ref
- 子組件內(nèi)不需要手動(dòng)綁定
Function組件
默認(rèn)情況下,不能在函數(shù)組件上使用 ref 屬性,因?yàn)樗鼈儧]有實(shí)例。所以上面的兩種方式是行不通的。
解決辦法就是使用 forwardRef 和 useImperativeHandle。
不過在函數(shù)的內(nèi)部是可以使用 useRef 鉤子來獲取組件內(nèi)的 DOM 元素。
Parent.js
import React, { useRef } from 'react';
import Child from './Child';
const Parent = () => {
// 通過 Hooks 創(chuàng)建 Ref
const childRef = useRef(null)
const handleClick = () => {
childRef.current.sendMessage()
}
return (
<>
<Child
ref={childRef}
/>
<button onClick={handleClick}>Trigger Child Event</button>
</>
);
}
export default Parent;
Child.js
import React, { forwardRef, useImperativeHandle } from 'react';
const Child = forwardRef((props, ref) => {
//將子組件的方法 暴露給父組件
useImperativeHandle(ref, () => ({
sendMessage
}))
const sendMessage = () => {
console.log('sending message')
}
return ( <div>Child</div> );
})
export default Child;
注:
上面的例子中只是簡單地演示了父子組件之間的方法調(diào)用,當(dāng)然實(shí)際情況中子組件中可以也會(huì)有自己的 ref 指向自己內(nèi)部的 DOM 元素,不過這些原理都是一樣的。
補(bǔ)充:子組件調(diào)用父組件方法
子組件中調(diào)用父組件的setId方法
父組件
<NavBarX
item={item}
current={current}
getBatchDetails={(id) => this.getBatchDetails(0, id)}
setId={(id, callback) => this.setState({ id }, callback)}
onRef={this.onNavBarXRef}
/>
子組件
this.props.setId(prePageId, () => {
getBatchDetails(prePageId)
})
總結(jié)
到此這篇關(guān)于React父組件調(diào)用子組件中方法的文章就介紹到這了,更多相關(guān)React父組件調(diào)用子組件方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用React實(shí)現(xiàn)一個(gè)簡單的待辦任務(wù)列表
這篇文章主要給大家介紹了使用React和Ant Design庫構(gòu)建的待辦任務(wù)列表應(yīng)用,它包含了可編輯的表格,用戶可以添加、編輯和完成任務(wù),以及保存任務(wù)列表數(shù)據(jù)到本地存儲(chǔ),文中有相關(guān)的代碼示例,需要的朋友可以參考下2023-08-08
React Native實(shí)現(xiàn)簡單的登錄功能(推薦)
這篇文章主要介紹了React Native實(shí)現(xiàn)登錄功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09
React videojs 實(shí)現(xiàn)自定義組件(視頻畫質(zhì)/清晰度切換) 的操作代碼
最近使用videojs作為視頻處理第三方庫,用來對(duì)接m3u8視頻類型,這里總結(jié)一下自定義組件遇到的問題及實(shí)現(xiàn),感興趣的朋友跟隨小編一起看看吧2023-08-08
React-router 4 按需加載的實(shí)現(xiàn)方式及原理詳解
本篇文章主要介紹了React-router 4 按需加載的實(shí)現(xiàn)方式及原理詳解,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05

