sourcecode

리액트 라우터돔을 사용할 때 '기능 구성 요소를 참조할 수 없음'을 방지하려면 어떻게 해야 합니까?

copyscript 2023. 2. 28. 23:42
반응형

리액트 라우터돔을 사용할 때 '기능 구성 요소를 참조할 수 없음'을 방지하려면 어떻게 해야 합니까?

다음을 가지고 있습니다(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()를 사용하시겠습니까?

렌더링 방법을 확인합니다.ForwardRefNavLink (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-routerhttps://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

반응형