에러- Styled Component 에 Ref 전달해주기 -forwardRef

최문길·2023년 11월 22일
1

react

목록 보기
3/14
post-thumbnail
{
post.map(el=> 
<DivContainer key={el.id} ref={(props) => (textRef["id"] = el.id)}>
  <Div>
  <img src={el.imgurl} alt="photo" />
    
    // 아... 에러에러
    <TextArea $isEdit={el.isEdit} defaultValue={el.text} ref={textRef} />
      
      {!el.isEdit ? (
       <Btn onClick={handleEdit(el.id)}>수정</Btn>
		) : (
  		<Btn onClick={handleUpdate(el.text)}>업뎃</Btn>
	   )}
  <Btn>삭제</Btn>
</Div>
</DivContainer>
)
}

데이터를 받아와서 map으로 컴포넌트를 만들고 나의 칭구친구 콘솔을 확인하였는데

error

징짜...

딱 봐도 예전에 useRef 공부하면서 forwadRef를 배웠고, 개인 프로젝트 할 때 써야 할 상황이 있었는데,

마음이 급급해서 다른 방법으로 우회 했는데, 결국 맞닥드렸다..

교훈
맞닥드렸다가 회피하면 결국 다시 맞닥드린다. . .
물론 내가 로직을 잘못 짠것일 수도있다는 생각은 늘 가진다. 😂😁

forwadRef를 사용 하는 이유는

  • 함수형 컴포넌트는 인스턴스가 없기 때문에 ref 속성을 사용할 수 없다.

  • 따라서, 함수형 컴포넌트를 forwardRef로 감싸주게 되면 ref를 사용할 수 있다.
    (+ 클래스로 선언된 컴포넌트들은 인스턴스를 가지기 때문에 ref 속성 사용 가능)

  • 부모 컴포넌트에서 자식 컴포넌트 안의 DOM element에 접근하고 싶을 때 사용한다.

등등이 있지만,

내 생각에는 useRef를 자식 한테 전달해서 사용하고 싶으면 사용하는 것 같다.

우째 똑같은데 위의 말하고 ..😂

아무튼 해결은 했다. 잠깐 생각했지만 ( 한 30분 한듯...)

처음에는

 {post.map((el, i) => {
        return (
          <DivContainer key={el.id} ref={(props) => (textRef["id"] = el.id)}>
            <Div>
              <img src={el.imgurl} alt="" />

              <TextAreaForwad $isEdit={el.isEdit} defaultValue={el.text} ref={textRef} />

              {!el.isEdit ? (
                <Btn onClick={handleEdit(el.id)}>수정</Btn>
              ) : (
                <Btn onClick={handleUpdate(el.text)}>업뎃</Btn>
              )}
              <Btn>삭제</Btn>
            </Div>
          </DivContainer>
        );
      })}
  </div>
}

const TextAreaForwad = forwardRef(({ props }, ref) => {
  return <TextArea $isEdit={props.isEdit} defaultValue={props.text} ref={ref} />;
});

const TextArea = styled.textarea.attrs((props) => ({
  readOnly: props.$isEdit === false ? true : false
}))`
  resize: none;
  width: 200px;
  padding: 20px;
  cursor: text;
`;

위 코드처럼 무식하게 저렇게 하면 알아서 잘 될 줄 알았지만... 사실 내 소원이었지만

안되는게 당연했다.

내가 받고 싶은 것을 props와 ref로 아래의 TextArea에 전달 해야 하는 것인데

사실 지금 생각하면 당연한 건데,, 계속 밤새고 그러다 보니 머리회전이 잘 안되나 보다..

다시 돌아와서

forwadRef 사용하는 로직

내가 사용할 컴포넌트를 forwardRef로 감싸주고, 컴포넌트가, style 컴포넌트등.. 머 암튼

'새로운' 컴포넌트를 만들어 준다.

  // forwardRef도 컴포넌트다 결국은!! 다만 ref까지 받을 수 있는 좋은 컴포넌트이다.
const TextAreaForwad = forwardRef(({ props }, ref) => {
  return <TextArea $isEdit={props.isEdit} defaultValue={props.text} ref={ref} />;
});

새로운 컴포넌트이기에 당연히 이 친구에게 props전달을 하는 것도 가능할 뿐더러

ref까지 전달하여 사용 가능하게 해준다.

따라서 ..

const textRef=useRef()
{post.map((el, i) => {
  return (
    <DivContainer key={el.id} ref={(props) => (textRef["id"] = el.id)}>
  		<Div>
 		 <img src={el.imgurl} alt="" />
         // 그냥 el,과 i ref까지 전달 받는 컴포넌트 일뿐 
    	<TextAreaForwad props={el} ref={textRef} />
      {!el.isEdit ? (
       <Btn onClick={handleEdit(el.id)}>수정</Btn>
		) : (
  		<Btn onClick={handleUpdate(el.text)}>업뎃</Btn>
	  )}
  	<Btn>삭제</Btn>
</Div>
</DivContainer>
);
})}
const TextAreaForwad = forwardRef(({ props }, ref) => {
  return <TextArea $isEdit={props.isEdit} defaultValue={props.text} ref={ref} />;
});
const TextArea = styled.textarea.attrs((props) => ({
  readOnly: props.$isEdit === false ? true : false
}))`

이렇게 부모컴포넌트의 ref, props 둘다 자식요소에 주고 싶으면 forward로 감싼 '새로운' 컴포넌트를 만들어

전달 받자...

0개의 댓글