我正在开发我的第一个 React Native 应用程序。我想要实现的是从父组件执行子函数,这就是情况:
孩子
export default class Child extends Component {
...
myfunct: function() {
console.log('Managed!');
}
...
render(){
return(
<Listview
...
/>
);
}
}
家长
export default class Parent extends Component {
...
execChildFunct: function() {
...
//launch child function "myfunct"
...
//do other stuff
}
render(){
return(
<View>
<Button onPress={this.execChildFunct} />
<Child {...this.props} />
</View>);
}
}
在这个例子中,我想在按下父类中的按钮时记录
'Managed!'
。怎么可行?
以下是如何使用功能组件来做到这一点:
家长
useRef()
为子组件在父组件中提供引用:const childRef = useRef()
// ...
return (
<ChildComponent ref={childRef} />
)
...
孩子
ref
作为构造函数参数之一传递:const ChildComponent = (props, ref) => {
// ...
}
useImperativeHandle
库导入 forwardRef
和 'react'
方法:import React, { useImperativeHandle, forwardRef } from 'react'
useImperativeHandle
将函数绑定到 ref
对象,这将使父级可以访问这些函数这些方法在内部不可用,因此您可能想使用它们来调用内部方法。
const ChildComponent = (props, ref) => {
//...
useImperativeHandle(ref, () => ({
// each key is connected to `ref` as a method name
// they can execute code directly, or call a local method
method1: () => { localMethod1() },
method2: () => { console.log("Remote method 2 executed") }
}))
//...
// These are local methods, they are not seen by `ref`,
const localMethod1 = () => {
console.log("Method 1 executed")
}
// ..
}
forwardRef
导出子组件:const ChildComponent = (props, ref) => {
// ...
}
export default forwardRef(ChildComponent)
子组件
import React, { useImperativeHandle, forwardRef } from 'react';
import { View } from 'react-native'
const ChildComponent = (props, ref) => {
useImperativeHandle(ref, () => ({
// methods connected to `ref`
sayHi: () => { sayHi() }
}))
// internal method
const sayHi = () => {
console.log("Hello")
}
return (
<View />
);
}
export default forwardRef(ChildComponent)
父组件
import React, { useRef } from 'react';
import { Button, View } from 'react-native';
import ChildComponent from './components/ChildComponent';
const App = () => {
const childRef = useRef()
return (
<View>
<ChildComponent ref={childRef} />
<Button
onPress={() => {
childRef.current.sayHi()
}}
title="Execute Child Method"
/>
</View>
)
}
export default App
Expo Snacks 上有一个互动演示: https://snack.expo.dev/@backupbrain/calling-functions-from-other-components
这个解释是根据这篇TutorialsPoint文章
修改的Nader Dabit 的答案已经过时,因为在 ref 属性中使用字符串文字已被弃用。自 2017 年 9 月起,我们将这样做:
<Child ref={child => {this.child = child}} {...this.props} />
<Button onPress={this.child.myfunc} />
相同的功能,但我们不使用字符串来引用组件,而是将其存储在全局变量中。
您可以向子组件添加引用:
<Child ref='child' {...this.props} />
然后像这样调用孩子的方法:
<Button onPress={this.refs.child.myfunc} />
它正在反应。希望对你有帮助。
class Child extends React.Component {
componentDidMount() {
this.props.onRef(this)
}
componentWillUnmount() {
this.props.onRef(null)
}
method() {
console.log('do stuff')
}
render() {
return <h1>Hello World!</h1>
}
}
class EnhancedChild extends React.Component {
render() {
return <Child {...this.props} />
}
}
class Parent extends React.Component {
onClick = () => {
this.child.method() // do stuff
};
render() {
return (
<div>
<EnhancedChild onRef={ref => (this.child = ref)} />
<button onClick={this.onClick}>Child.method()</button>
</div>
);
}
}
ReactDOM.render(<Parent />, document.getElementById('root'))
原始解决方案:
父级 --> 子级函数调用的简单方法
/* Parent.js */
import React, { Component } from "react";
import { TouchableOpacity, Text } from "react-native";
import Child from "./Child";
class Parent extends React.Component {
onChildClick = () => {
this.child.childFunction(); // do stuff
};
render() {
return (
<div>
<Child onRef={(ref) => (this.child = ref)} />
<TouchableOpacity onClick={this.onChildClick}>
<Text>Child</Text>
</TouchableOpacity>
</div>
);
}
}
/* Child.js */
import React, { Component } from "react";
class Child extends React.Component {
componentDidMount() {
this.props.onRef(this);
}
componentWillUnmount() {
this.props.onRef(undefined);
}
childFunction() {
// do stuff
alert("childFunction called");
}
render() {
return <View>Hello World!</View>;
}
}
原始解决方案: https://github.com/kriasoft/react-starter-kit/issues/909
我认为你对组件结构有一些误解。
假设您的子组件是一个为其他组件生成按钮的组件。在这个层次结构中,您的孩子必须通知其父母它被按下了。
孩子----->父母
export default class Child extends Component {
return(
<Button onPress={this.props.onPress } />
);
}
在您的父组件中使用子组件为您生成一个按钮。这样你就可以使用任何其他组件的子组件作为独立按钮。
export default class Parent extends Component {
constructor(props) {
super(props);
this.execChildFunct=this.execChildFunct.bind(this)
}
execChildFunct: function() {
console.log('Managed!');
}
return (
<Child onPress = {this.execChildFunct}></Child>
)
}
这是我的源代码,例如:
子组件:
/* Child.js */
import React from 'react'
class Child extends React.Component {
componentDidMount() {
this.props.onRef(this) //-> important
}
componentWillUnmount() {
this.props.onRef(undefined)
}
onChange() {
alert('ok success')
}
render() {
return <View><Text>Hello World!</Text><View>
}
}
export default (Child);
父组件:
/* Parent.js */
import React from 'react'
import Child from './Child'
class Parent extends React.Component {
onShow = () => {
this.child.onChange()
}
render() {
return (
<View>
<Child onRef={ref => (this.child = ref)} /> //-> important
<Button onPress={()=>this.onShow()} title={"button check"}/>
</View>
);
}
}
祝你好运!