리액트 라우터돔을 사용할 때 '기능 구성 요소를 참조할 수 없음'을 방지하려면 어떻게 해야 합니까?
다음을 가지고 있습니다(Material UI 사용).
import React from "react";
import { NavLink } from "react-router-dom";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
function LinkTab(link){
return <Tab component={NavLink}
to={link.link}
label={link.label}
value={link.link}
key={link.link}
/>;
}
새 버전에서는 다음과 같은 경고가 발생합니다.
경고:함수 구성 요소는 참조를 제공할 수 없습니다.이 참조에 액세스하려고 하면 실패합니다.React.forwardRef()를 사용하시겠습니까?
렌더링 방법을 확인합니다.
ForwardRef
NavLink (ForwardRef에 의해 작성)
바꿔보려고 했는데...
function LinkTab(link){
// See https://material-ui.com/guides/composition/#caveat-with-refs
const MyLink = React.forwardRef((props, ref) => <NavLink {...props} ref={ref} />);
return <Tab component={MyLink}
to={link.link}
label={link.label}
value={link.link}
key={link.link}
/>;
}
하지만 난 여전히 경고를 받는다.이 문제를 해결하려면 어떻게 해야 하나요?
라고만 해 주세요.innerRef
,
// Client.js
<Input innerRef={inputRef} />
로서 사용하다ref
.
// Input.js
const Input = ({ innerRef }) => {
return (
<div>
<input ref={innerRef} />
</div>
)
}
NavLink
부터react-router
이 기능은 링크의 특수 버전입니다.이러한 컴포넌트에서는innerRef
그 목적을 위한 지지대.
// required for react-router-dom < 6.0.0
// see https://github.com/ReactTraining/react-router/issues/6056#issuecomment-435524678
const MyLink = React.forwardRef((props, ref) => <NavLink innerRef={ref} {...props} />);
우리 문서를 검색해서react-router
https://mui.com/getting-started/faq/ #how-do-i-use-messages-messages로 이동합니다.https://mui.com/components/buttons/ #third-party-messages-messages로 링크됩니다.마지막 링크에서는 동작 예를 보여 줍니다.또, 리액트 라우터 v6에서 이것이 어떻게 변경되는지도 설명하고 있습니다.
참조 대신 참조를 사용할 수 있습니다.이것은 특별한 소품명 ref를 회피하기 위해서만 기능합니다.
<InputText
label="Phone Number"
name="phoneNumber"
refs={register({ required: true })}
error={errors.phoneNumber ? true : false}
icon={MailIcon}
/>
커스텀을 추가할 수 없는 경우ref
프로펠러나 컴포넌트에 대해서도 기능 컴포넌트의 ref 오브젝트를 얻을 수 있는 요령이 있습니다.
다음과 같은 사용자 정의 기능 구성요소에 ref를 추가한다고 가정합니다.
const ref = useRef();
//throws error as Button is a functional component without ref prop
return <Button ref={ref}>Hi</Button>;
범용 html 요소로 랩하여 설정할 수 있습니다.ref
그 점에 대해서요.
const ref = useRef();
// This ref works. To get button html element inside div, you can do
const buttonRef = ref.current && ref.current.children[0];
return (
<div ref={ref}>
<Button>Hi</Button>
</div>
);
물론 그에 따라 상태를 관리하고 buttonRef 객체를 사용할 위치를 지정합니다.
우리의 경우 SVG 컴포넌트(Site's Logo)를 NextJS의 Link Component에 직접 전달하고 있었는데, 조금 커스터마이즈 되어 있어서 오류가 발생하고 있었습니다.
SVG가 사용되어 문제의 원인이 된 헤더 컴포넌트.
import Logo from '_public/logos/logo.svg'
import Link from '_components/link/Link'
const Header = () => (
<div className={s.headerLogo}>
<Link href={'/'}>
<Logo />
</Link>
</div>
)
콘솔 오류 메시지
Function components cannot be given refs. Attempts to access this ref will fail.
Did you mean to use React.forwardRef()?
맞춤 링크 컴포넌트
import NextLink from 'next/link'
import { forwardRef } from 'react'
const Link = ({ href, shallow, replace, children, passHref, className }, ref) => {
return href ? (
<NextLink
href={href}
passHref={passHref}
scroll={false}
shallow={shallow}
replace={replace}
prefetch={false}
className={className}
>
{children}
</NextLink>
) : (
<div className={className}>{children}</div>
)
}
export default forwardRef(Link)
커스터마이즈된 링크 컴포넌트에서 forwardRef를 사용하고 있는 것을 확인했지만, 아직 에러가 발생하고 있습니다.
이를 해결하기 위해 SVG 요소의 래퍼 위치를 다음과 같이 변경했습니다. :poof:
const Header = () => (
<Link href={'/'}>
<div className={s.headerLogo}>
<Logo />
</div>
</Link>
)
이 경고를 수정하려면 커스텀 컴포넌트를forwardRef
이 블로그에서 언급한 바와 같이 매우 잘 기능한다
const AppTextField =(props) {return(/*your component*/)}
상기의 코드를 로 변경하다
const AppTextField = forwardRef((props,ref) {return(/*your component*/)}
const renderItem = ({ item, index }) => {
return (
<>
<Item
key={item.Id}
item={item}
index={index}
/>
</>
);
};
Fragment를 사용하여 React.forwardRef() 경고를 해결합니다.
기능 컴포넌트를 사용하는 경우 React.forwardRef는 이러한 시나리오에서 사용하는 방법을 이해하는 데 매우 유용한 기능입니다.누가 이걸 읽게 되면 더 많은 실습을 할 수 있게 코드와 상자를 조립해놨어요Styled-Components가 처음에 로드되지 않을 수 있으므로 샌드박스가 로드될 때 인라인 브라우저를 새로 고쳐야 할 수 있습니다.
https://codesandbox.io/s/react-forwardref-example-15ql9t?file=/src/App.tsx
// MyAwesomeInput.tsx
import React from "react";
import { TextInput, TextInputProps } from "react-native";
import styled from "styled-components/native";
const Wrapper = styled.View`
width: 100%;
padding-bottom: 10px;
`;
const InputStyled = styled.TextInput`
width: 100%;
height: 50px;
border: 1px solid grey;
text-indent: 5px;
`;
// Created an interface to extend the TextInputProps, allowing access to all of its properties
// from the object that is created from Styled-Components.
//
// I also define the type that the forwarded ref will be.
interface AwesomeInputProps extends TextInputProps {
someProp?: boolean;
ref?: React.Ref<TextInput>;
}
// Created the functional component with the prop type created above.
//
// Notice the end of the line, where you wrap everything in the React.forwardRef().
// This makes it take one more parameter, called ref. I showed what it looks like
// if you are a fan of destructuring.
const MyAwesomeInput: React.FC<AwesomeInputProps> = React.forwardRef( // <-- This wraps the entire component, starting here.
({ someProp, ...props }, ref) => {
return (
<Wrapper>
<InputStyled {...props} ref={ref} />
</Wrapper>
);
}); // <-- And ending down here.
export default MyAwesomeInput;
그런 다음 호출 화면에서 참조 변수를 생성하여 구성 요소의 참조 필드에 전달합니다.
// App.tsx
import React from "react";
import { StyleSheet, Text, TextInput, View } from "react-native";
import MyAwesomeInput from "./Components/MyAwesomeInput";
const App: React.FC = () => {
// Set some state fields for the inputs.
const [field1, setField1] = React.useState("");
const [field2, setField2] = React.useState("");
// Created the ref variable that we'll use down below.
const field2Ref = React.useRef<TextInput>(null);
return (
<View style={styles.app}>
<Text>React.forwardRef Example</Text>
<View>
<MyAwesomeInput
value={field1}
onChangeText={setField1}
placeholder="field 1"
// When you're done typing in this field, and you hit enter or click next on a phone,
// this makes it focus the Ref field.
onSubmitEditing={() => {
field2Ref.current.focus();
}}
/>
<MyAwesomeInput
// Pass the ref variable that's created above to the MyAwesomeInput field of choice.
// Everything should work if you have it setup right.
ref={field2Ref}
value={field2}
onChangeText={setField2}
placeholder="field 2"
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
app: {
flex: 1,
justifyContent: "center",
alignItems: "center"
}
});
export default App;
그렇게 간단해!MyAwesome을 어디에 두든입력 구성 요소 참조를 사용할 수 있습니다.
요.skychavda
솔루션(자녀에 대한 참조를 제공하므로): 따라서 경고 없이 부모로부터 직접 자식 메서드 또는 자식 참조를 호출할 수 있습니다.
출처 : https://github.com/reactjs/reactjs.org/issues/2120
/* Child.jsx */
import React from 'react'
class Child extends React.Component {
componentDidMount() {
const { childRef } = this.props;
childRef(this);
}
componentWillUnmount() {
const { childRef } = this.props;
childRef(undefined);
}
alertMessage() {
window.alert('called from parent component');
}
render() {
return <h1>Hello World!</h1>
}
}
export default Child;
/* Parent.jsx */
import React from 'react';
import Child from './Child';
class Parent extends React.Component {
onClick = () => {
this.child.alertMessage(); // do stuff
}
render() {
return (
<div>
<Child childRef={ref => (this.child = ref)} />
<button onClick={this.onClick}>Child.alertMessage()</button>
</div>
);
}
}
언급URL : https://stackoverflow.com/questions/56484686/how-do-i-avoid-function-components-cannot-be-given-refs-when-using-react-route
'sourcecode' 카테고리의 다른 글
PL/SQL 블록에서 SELECT 문을 출력할 수 있습니까? (0) | 2023.02.28 |
---|---|
구텐베르크 커스텀 배너 블록 페이지 제목 사용 (0) | 2023.02.28 |
요소가 존재하지 않는지 프로젝터 확인 (0) | 2023.02.23 |
Spring Rest템플릿 예외 처리 (0) | 2023.02.23 |
사용자 정의 필터 기능이 있는 AngularJS 다중 필터 (0) | 2023.02.23 |