从父级调用功能组件的子级方法

时间:2021-02-14 07:32:35

标签: reactjs typescript react-native

我没有使用课程,我想学习如何手动完成。我正在处理登录屏幕。 https://snack.expo.io/@ericsia/call-function-from-child-component 如果您想向我展示您的代码,您需要保存并分享链接。所以我想要一个用于显示文本框的功能组件(假设 ChildComponent 作为函数名称,所以 export ChildComponent)。
所以在 Parent/Screen1 中,我有类似的东西吗?

import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import Constants from 'expo-constants';

// You can import from local files
import ChildComponent from './components/ChildComponent';

export default function App() {
  
  function checkSuccess()
  {
    // call helloWorld from here
  }
  return (
    <View style={styles.container}>
   
        <ChildComponent />
    
        <TouchableOpacity style={styles.button}
        onPress={ checkSuccess } >
        <Text>helloWorld ChildComponent</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  button: {
    alignItems: "center",
    backgroundColor: "#DDDDDD",
    padding: 10
  },
});

所以如果结果是无效的,我想显示一个微小的红色错误消息。 something like this 我的方法是,如果我可以从 ChildComponent 调用一个函数,那么我仍然可以解决它。
我用谷歌搜索了一下,提供的大部分解决方案都是针对课堂的。 我试过 useEffect React.createRef useImperativeHandle,但没有成功。
首先,我只是想调用 helloWorld()

import * as React from 'react';
import { TextInput , View, StyleSheet, Image } from 'react-native';

export default function ChildComponent() {
  function helloWorld()
  {
    alert("Hello World");
  }
  return (<TextInput placeholder="Try to call helloWorld from App.js"/>);
}

另一个问题,如果我的 ChildComponent 中有一个文本框,我如何从父级检索文本/值?

1 个答案:

答案 0 :(得分:0)

简单的方法:传递道具

您可以将 helloWorld 函数向上移动到父组件,并将其作为 prop 向下传递给子组件。这样两个组件都可以调用它。当您要传递函数时,我建议使用 arrow function,尽管在这种情况下无关紧要。

家长

export default function App() {
  const helloWorld = () => {
    alert('Hello World');
  }
  const checkSuccess = () => {
    helloWorld();
  }

  return (
    <View style={styles.container}>
      <ChildComponent helloWorld={helloWorld} />
      <TouchableOpacity style={styles.button} onPress={checkSuccess}>
        <Text>helloWorld ChildComponent</Text>
      </TouchableOpacity>
    </View>
  );
}

孩子

const ChildComponent = ({ helloWorld }) => {
  // could do anything with helloWorld here

  return <TextInput placeholder="Try to call helloWorld from App.js" />;
};

艰难的方式:参考转发

如果你想把这个函数保留在子组件中,那么你需要经历很多麻烦。我不推荐这种方法。

您必须完成所有这些步骤:

  • 使用 useRef 在父对象中创建一个 ref 对象:const childRef = React.useRef();
  • 将 ref 作为道具传递给孩子:<ChildComponent ref={childRef} />
  • 在子组件 ref 的当前值上调用该函数,如果尚未设置 ?.,则使用 .current 以避免错误:childRef.current?.helloWorld();
  • 使用 forwardRef 接受子项中的 ref 道具:React.forwardRef( (props, ref) => {
  • 使用 useImperativeHandlehelloWorld 函数公开为子组件的实例变量:React.useImperativeHandle(ref , () => ({helloWorld}));

家长:

export default function App() {
  const childRef = React.useRef();

  function checkSuccess() {
    childRef.current?.helloWorld();
  }

  return (
    <View style={styles.container}>
      <ChildComponent ref={childRef} />
      <TouchableOpacity style={styles.button} onPress={checkSuccess}>
        <Text>helloWorld ChildComponent</Text>
      </TouchableOpacity>
    </View>
  );
}

孩子:

const ChildComponent = React.forwardRef((props, ref) => {
  function helloWorld() {
    alert('Hello World');
  }

  React.useImperativeHandle(ref, () => ({ helloWorld }));

  return <TextInput placeholder="Try to call helloWorld from App.js" />;
});

编辑:Expo Link