从React Native中的父组件调用子函数

o7jaxewo  于 2023-03-13  发布在  React
关注(0)|答案(7)|浏览(184)

我正在开发我的第一个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!',怎么可能呢?

wvyml7n5

wvyml7n51#

Nader Dabit的回答已经过时了,因为在ref属性中使用String常量已经被弃用了。以下是截至2017年9月的做法:

<Child ref={child => {this.child = child}} {...this.props} />
<Button onPress={this.child.myfunc} />

相同的功能,但不是使用String来引用组件,而是将其存储在全局变量中。

fjaof16o

fjaof16o2#

下面是如何使用功能组件实现这一点:

家长

1.使用useRef()在父元件中为子元件提供一个引用:

const childRef = useRef()
// ...
return (
   <ChildComponent ref={childRef} />
)
...

儿童

1.将ref作为构造函数参数之一传递:

const ChildComponent = (props, ref) => {
  // ...
}

1.从'react'库导入useImperativeHandleforwardRef方法:

import React, { useImperativeHandle, forwardRef } from 'react'

1.使用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")
  }
  // ..
}

1.使用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 article修改的

bt1cpqcv

bt1cpqcv3#

可以向子组件添加引用:

<Child ref='child' {...this.props} />

然后像这样调用子对象上的方法:

<Button onPress={this.refs.child.myfunc} />
t8e9dugd

t8e9dugd4#

正在回复中,希望对你有所帮助

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'))

原始溶液:

https://jsfiddle.net/frenzzy/z9c46qtv/
https://github.com/kriasoft/react-starter-kit/issues/909

x33g5p2x

x33g5p2x5#

简单易行的父--〉子函数调用方法

/* 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

14ifxucb

14ifxucb6#

我想你对组件结构有些误解了。
假设你的孩子是一个为其他组件生成按钮的组件,在这个层次结构中,你的孩子必须通知它的父亲它被按下了。
子级-----〉父级

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>
  )

}
bvpmtnay

bvpmtnay7#

这是我的源代码例如:

子组件:

/* 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>
    );
  }
}

祝你好运!

相关问题