在 react-native 中调用其他组件的函数
Calling functions from other components in react-native
如何在 react-native 中调用其他组件的函数?
我有这个自定义组件,它呈现在其他地方定义的另一个组件和一个图像按钮。点击图像时,我想从其他组件调用一个函数。执行下面的示例时,我得到 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>
);
}
}
和
export default class OtherComponent extends Component {
addTag() {
this.state.tags = this.state.tags.push("plm");
console.log('success..');
}
....
}
不建议组件之间直接通信,因为它会破坏封装。向组件发送 prop 并让它处理方法内的更改是一个很好的做法 componentWillReceiveProps
.
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 };
}
componentWillReceiveProps(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.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"/>
不必在class里面定义函数。这是一个例子
在helpers.js
export async function getAccessKey(){
let accessToken = await AsyncStorage.getItem(ACCESS_TOKEN);
return accessToken;
}
在调用class.
import { getAccessKey } from '../components/helpers';
...
//inside the method
let key = await getAccessKey();
在功能组件中调用远程方法
要对功能组件执行此操作,您必须执行以下操作:
Parent
- 使用
useRef()
: 在 parent 中给 child 组件一个引用
const childRef = useRef()
// ...
return (
<ChildComponent ref={childRef} />
)
...
Child
- 将
ref
传递给构造函数:
const ChildComponent = (props, ref) => {
// ...
}
- 从
'react'
导入 useImperativeHandle
和 forwardRef
:
import React, { useImperativeHandle, forwardRef } from 'react'
- 使用
useImperativeHandle
将方法连接到 ref
object。
这些方法在内部不可用,因此您可能希望使用它们来调用内部方法。
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")
}
// ..
}
- 导出 child 组件使用
forwardRef
:
const ChildComponent = (props, ref) => {
// ...
}
export default forwardRef(ChildComponent)
综合起来
Child 组件
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 组件
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
如何在 react-native 中调用其他组件的函数?
我有这个自定义组件,它呈现在其他地方定义的另一个组件和一个图像按钮。点击图像时,我想从其他组件调用一个函数。执行下面的示例时,我得到 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>
);
}
}
和
export default class OtherComponent extends Component {
addTag() {
this.state.tags = this.state.tags.push("plm");
console.log('success..');
}
....
}
不建议组件之间直接通信,因为它会破坏封装。向组件发送 prop 并让它处理方法内的更改是一个很好的做法 componentWillReceiveProps
.
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 };
}
componentWillReceiveProps(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.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"/>
不必在class里面定义函数。这是一个例子
在helpers.js
export async function getAccessKey(){
let accessToken = await AsyncStorage.getItem(ACCESS_TOKEN);
return accessToken;
}
在调用class.
import { getAccessKey } from '../components/helpers';
...
//inside the method
let key = await getAccessKey();
在功能组件中调用远程方法
要对功能组件执行此操作,您必须执行以下操作:
Parent
- 使用
useRef()
: 在 parent 中给 child 组件一个引用
const childRef = useRef()
// ...
return (
<ChildComponent ref={childRef} />
)
...
Child
- 将
ref
传递给构造函数:
const ChildComponent = (props, ref) => {
// ...
}
- 从
'react'
导入useImperativeHandle
和forwardRef
:
import React, { useImperativeHandle, forwardRef } from 'react'
- 使用
useImperativeHandle
将方法连接到ref
object。
这些方法在内部不可用,因此您可能希望使用它们来调用内部方法。
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")
}
// ..
}
- 导出 child 组件使用
forwardRef
:
const ChildComponent = (props, ref) => {
// ...
}
export default forwardRef(ChildComponent)
综合起来
Child 组件
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 组件
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