#react-native #react-native-android #react-native-ios
#react-native #react-native-android #react-native-ios
Вопрос:
Я разрабатываю проект react-native.
Я создал пользовательский компонент, внутри которого я использую сторонний библиотечный компонент. Стороннему библиотечному компоненту требуется useRef
перехват из моего кода, чтобы я мог управлять библиотечным компонентом.
import React, {useRef} from 'react';
...
const MyComponent = () => {
const ref = useRef();
return (
<View>
<Button
title="OPEN 3rd party component"
onPress={() => ref.current.open()}
/>
<LibraryComponent
ref={ref}
...
/>
</View>)
}
Теперь у меня есть экран с именем MyScreen
, который мне нужно отобразить MyComponent
MyScreen
, и управлять этим библиотечным компонентом MyScreen
вместо MyComponent
. Итак, я переработал MyComponent
это (я удалил Button
и изменил ref
, чтобы быть передающим свойством):
const MyComponent = ({ref}) => {
return (
<View>
<LibraryComponent
ref={ref}
...
/>
</View>)
}
Затем в MyScreen
:
import React, {useRef} from 'react';
import MyComponent from '../components/MyComponent';
export const MyScreen = () => {
const screenRef = useRef();
...
return (
<View style={styles.container}>
<Button onPress=>{()=>screenRef.current.open()}/>
<MyComponent ref={screenRef}>
...
</View>
)
}
Но я получаю предупреждающее сообщение: Function components cannot be give refs. Attempts to access this ref will fail. Did you mean to use React.ForwardRef() ?
Мои вопросы:
Как избавиться от этого предупреждения и MyScreen
контролировать библиотечный компонент с помощью ссылочного крючка?
======== ОБНОВЛЕНИЕ =======
Я изменил имя свойства в MyComponent
from ref
на innerRef
, как предложил @Rishabh Anand. Предупреждение исчезло.
const MyComponent = ({innerRef}) => {
...
}
MyScreen теперь:
export const MyScreen = () => {
const screenRef = useRef();
...
return (
<View style={styles.container}>
<Button onPress=>{()=>screenRef.current.open()}/>
<MyComponent innerRef={screenRef}>
...
</View>
)
}
Но теперь возникает новая проблема: когда я нажимаю на Button
of MyScreen
, приложение завершает работу с ошибкой undefined is not an object (evaluating screenRef.current.open)
. Кажется screenRef.current
null
, что вместо компонента библиотеки используется a. Почему?
Комментарии:
1.
ref
это ключевое слово в React, в основном каждый компонент будет иметь один и может быть установлен только для того, чтобы не передаваться дочернему компоненту. Если вы можете попробовать изменить имя изref
в MyScreen на что-то вродеinnerRef
, когда вы передаете prop в<MyComponent innerRef={screenRef} />
?2. @Rishabh, да, спасибо. Но теперь возникает новая проблема: когда я нажимаю на
Button
MyScreen, приложение завершает работу с ошибкойundefined is not an object (evaluating screenRef.current.open)
. КажетсяscreenRef.current
, что вместо библиотечного компонента содержит значение null. Вы знаете, почему?
Ответ №1:
Вы должны использовать React.forwardRef
Из документации: https://fr.reactjs.org/docs/forwarding-refs.html
const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} className="FancyButton">
{props.children}
</button>
));
const ref = React.createRef();
<FancyButton ref={ref}>Cliquez ici</FancyButton>;
После установки ссылки вы можете вызвать некоторую функцию внутри вашего дочернего компонента следующим образом:
const FancyButton = React.forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
click: () => {
onClick();
},
}));
const onClick = () => {
console.log('Clicked.');
};
return (
<button onClick={onClick} className="FancyButton">
{props.children}
</button>
);
});
const ref = React.createRef();
<FancyButton ref={ref}>Cliquez ici</FancyButton>;
И вызов из вашего родительского компонента
ref.current.click()