最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Calling functions from other components in react-native - Stack Overflow

programmeradmin6浏览0评论

How can I call functions from other ponents in react-native ?

I have this custom ponent which renders another ponent defined somewhere else and a image button. When tapping the image I want to call a function from the other ponent. When executing the example below I get undefined is not an object (evaluating this.otherComponent.doSomething')

export default class MainComponent extends Component {

  _onPressButton() {
    this.otherComponent.doSomething();
  }

  render() {
    return (
      <View style={styles.container}>
        <TagContainer style={styles.flow_container} ref={(instance) => this.otherComponent = instance}>
        </TagContainer>
        <TouchableHighlight onPress={this._onPressButton}><Image source={require('./img/ic_add.png')} style={styles.add_tags_button_view} /></TouchableHighlight>
      </View>
    );
  }
}

and

export default class OtherComponent extends Component {

    addTag() {
        this.state.tags = this.state.tags.push("plm");
        console.log('success..');
    }

    ....
}

How can I call functions from other ponents in react-native ?

I have this custom ponent which renders another ponent defined somewhere else and a image button. When tapping the image I want to call a function from the other ponent. When executing the example below I get undefined is not an object (evaluating this.otherComponent.doSomething')

export default class MainComponent extends Component {

  _onPressButton() {
    this.otherComponent.doSomething();
  }

  render() {
    return (
      <View style={styles.container}>
        <TagContainer style={styles.flow_container} ref={(instance) => this.otherComponent = instance}>
        </TagContainer>
        <TouchableHighlight onPress={this._onPressButton}><Image source={require('./img/ic_add.png')} style={styles.add_tags_button_view} /></TouchableHighlight>
      </View>
    );
  }
}

and

export default class OtherComponent extends Component {

    addTag() {
        this.state.tags = this.state.tags.push("plm");
        console.log('success..');
    }

    ....
}
Share Improve this question asked May 13, 2017 at 13:37 adi.neagadi.neag 6432 gold badges12 silver badges27 bronze badges 2
  • shouldn't this be: this.refs.otherComponent.addTag(); ? and <TagContainer ref="otherComponent"></TagContainer> – funkysoul Commented May 13, 2017 at 13:50
  • reactnatve.wordpress./2016/05/24/refs-to-ponents – Pete Alvin Commented Nov 6, 2017 at 13:14
Add a ment  | 

3 Answers 3

Reset to default 12

Calling Remote Methods in Functional Components

To do this with functional ponents, you must do this:

Parent

  1. Give the child ponent a reference in the parent using useRef():
const childRef = useRef()
// ...
return (
   <ChildComponent ref={childRef} />
)
...

Child

  1. Pass ref into the constructor:
const ChildComponent = (props, ref) => {
  // ...
}
  1. Import useImperativeHandle and forwardRef from 'react':
import React, { useImperativeHandle, forwardRef } from 'react'
  1. Use useImperativeHandle to connect methods to the ref object.

These methods won't be internally available, so you may want to use them to call internal methods.

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. Export the child ponent using forwardRef:
const ChildComponent = (props, ref) => {
  // ...
}
export default forwardRef(ChildComponent)

Putting it all together

Child Component

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)

Parent Component

import React, { useRef } from 'react';
import { Button, View } from 'react-native';
import ChildComponent from './ponents/ChildComponent';

const App = () => {
  const childRef = useRef()
  return (
    <View>
      <ChildComponent ref={childRef} />
      <Button
        onPress={() => {
          childRef.current.sayHi()
        }}
        title="Execute Child Method"
      />
    </View>
  )
}

export default App

There is an interactive demo of this on Expo Snacks: https://snack.expo.dev/@backupbrain/calling-functions-from-other-ponents

This explanation is modified from this TutorialsPoint article

Direct munication between ponents is not remended, because it breaks encapsulation. It's a good practice to send a prop to the ponent and let it handles the change inside the method ponentWillReceiveProps.

class Main extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: 0 };
    this.handleClick = this.handleClick.bind(this);
  }
   
  handleClick(e) {
    e.preventDefault();
    this.setState({ value: ++this.state.value });
  }
  
  render() {
    return (
      <div>
        <a href="#" onClick={this.handleClick}>click me</a>
        <Child value={this.state.value}/>
      </div>
    );
  }
}


class Child extends React.Component {
  constructor(props) {
    super(props);
    
    this.state = { value: 0 };
  }
  
  ponentWillReceiveProps(nextProps) {
    if(nextProps.value !== this.state.value) {
      this.setState({ value: nextProps.value });
    }
  }
  
  render() {
    return <div>{this.state.value}</div>
  }
}


ReactDOM.render(<Main />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"/>

Need not have to define the function inside class . Here is an example

in the helpers.js

export async function getAccessKey(){
let accessToken =  await AsyncStorage.getItem(ACCESS_TOKEN);
return accessToken;
}

in the calling class.

import { getAccessKey } from '../ponents/helpers';
...
//inside the method
      let  key = await getAccessKey();
发布评论

评论列表(0)

  1. 暂无评论