Не удается вызвать метод дочернего компонента из родительского компонента в React Native

#javascript #reactjs #react-native

#javascript #reactjs #react-native

Вопрос:

У меня есть компонент React Native, <Parent> который содержит компонент <Child> , и я хочу иметь возможность вызывать один из дочерних методов в родительском. После прочтения кучи других сообщений, это то, что у меня есть:

Child.js

 export default class Child extends Component {
  method1() {
    console.log("success");
  }
  render() {
    return(
      <View/>
    )
  }
}
  

Родительский

 export default class Parent extends Component {
  render() {
    return(
      <View>
        <TouchableOpacity
          onPress={() => this.child.method1()}
        />
        <Child
          onRef={ref => (this.child = ref)}
        />
      </View>
    )
  }
}
  

Я получаю сообщение об ошибке «_this2.child.method1 не является функцией».

Другие вещи, которые я пробовал, — это использовать refInput вместо onRef и делать ref => {this.child = ref} вместо ref => (this.child = ref) .

Есть идеи?

Спасибо!

Комментарии:

1. какое-либо решение еще

Ответ №1:

Вы можете создать ссылку с помощью React.createRef в конструкторе и назначить ее экземпляру дочернего компонента с помощью ref prop

Сообщение о том, что вы можете получить доступ к дочернему компоненту с помощью this.child.current

Пример кода:

 class Child extends React.Component {
  myMethod() {
    console.log("myMethod called");
  }

  render() {
    return <Text>This is child</Text>;
  }
}

class App extends Component {
  constructor() {
    super();
    this.child = React.createRef();
  }
  render() {
    return (
      <View style={styles.app}>
        <View style={styles.header}>
          <Image
            accessibilityLabel="React logo"
            source={{ uri: logoUri }}
            resizeMode="contain"
            style={styles.logo}
          />
          <Text style={styles.title}>React Native for Web</Text>
        </View>
        <Child ref={this.child} />
        <Button
          onPress={() => {
            this.child.current.myMethod();
          }}
          title="Example button(Click to trigger Child)"
        />
      </View>
    );
  }
}
  

Рабочая демонстрация

ЕСЛИ ваш дочерний компонент подключен с помощью connect из redux, вы все равно можете получить доступ к дочерней ссылке, установив для параметра withRef значение true в connect

 connect(mapStateToProps, mapDispatchToProps, null, { withRef: true })(Child);
  

Если вы используете версию redux версии 6 или выше, установите свойство forwardRef вместо withRef

 connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true })(Child);
  

Как только вы сделаете это в родительском, вы сможете получить доступ к ссылке cchild с помощью

 this.child.current.getWrappedInstance()
  

Комментарии:

1. Это не работает, так говорят.child.current.myMethod не является функцией

2. Пожалуйста, проверьте демонстрацию. Это действительно работает. Также определите атрибут как ссылку на дочерний компонент

3. Можете ли вы посмотреть демонстрацию на мобильном устройстве, я уже рассказывал о ее работе на веб-платформе react

4. вы имеете в виду this.child.current.getWrappedInstance().methodName() правильно?

5. Спасибо, ты мой спаситель

Ответ №2:

Один из способов, которым вы можете это сделать, — передать дочернему элементу функцию, которой дочерний элемент может передать функцию. Например:

 <TouchableOpacity
  onPress={() => this.childFunc()}
/>
<Child addMethod={func => this.childFunc = func}/>
  

Тогда просто вызовите props.addFunc(this.method1) изнутри дочернего компонента. Просто убедитесь, что ваш this тот, который вам нужен.

Что еще более важно, вы должны спросить себя, зачем вам нужно это делать в первую очередь.

Ответ №3:

Используйте ref для вызова дочернего метода

 export default class Parent extends Component {
  render() {
    return(
      <View>
        <TouchableOpacity
          onPress={() => this.refs.child.method1()}//<---------
        />
        <Child
          ref="child"//<-------
        />
      </View>
    )
  }
}
  

Комментарии:

1.Вы предлагаете использовать устаревший API «Legacy API: ссылки на строки» «Мы не советуем этого делать, потому что ссылки на строки имеют некоторые проблемы, считаются устаревшими и, вероятно, будут удалены в одном из будущих выпусков

Ответ №4:

Наконец-то найдена проблема.

ответ @Shubham khatri определенно сработает, он не будет работать только с redux.

если ваш дочерний класс переносится с connect

 export default connect(mapStateToProps)(Athletes);
  

В этом случае это не сработает, поэтому убедитесь, что вы используете его обычным способом, если хотите вызвать дочерний метод из родительского класса.