programing

react useRef를 사용하는 대상 DOM이 맵에서 어떻게 표시되는지

oldcodes 2023. 2. 28. 23:46
반응형

react useRef를 사용하는 대상 DOM이 맵에서 어떻게 표시되는지

리액션이 있는 일련의 DOM 요소를 취득하기 위한 솔루션을 찾고 있습니다.useRef()갈고리를 채우다

예:

const Component = () => 
{

  // In `items`, I would like to get an array of DOM element
  let items = useRef(null);

  return <ul>
    {['left', 'right'].map((el, i) =>
      <li key={i} ref={items} children={el} />
    )}
  </ul>
}

어떻게 하면 좋을까요?

useRefReact와 부분적으로 비슷합니다.ref(필드의 필드만 있는 객체의 구조만current).

useRef훅은 렌더링 사이에 데이터를 저장하고 데이터가 재연결을 트리거하지 않도록 변경하는 것을 목표로 합니다(다른 것과 다름).useState하고 있습니다).

또, 루프내의 훅을 초기화하지 않는 것이 좋습니다.if후크의 첫 번째 규칙입니다

이 점을 염두에 두고 다음을 수행합니다.

  1. 어레이를 생성하여 렌더링 사이에 보관하는 방법useRef

  2. 각 어레이의 요소를 초기화합니다.createRef()

  3. 목록을 참조할 수 있습니다..current표기법

    const Component = () => {
    
      let refs = useRef([React.createRef(), React.createRef()]);
    
      useEffect(() => {
        refs.current[0].current.focus()
      }, []);
    
      return (<ul>
        {['left', 'right'].map((el, i) =>
          <li key={i}><input ref={refs.current[i]} value={el} /></li>
        )}
      </ul>)
    }
    

이렇게 하면 어레이를 안전하게 변경할 수 있습니다(예를 들어 어레이의 길이를 변경할 수 있습니다.단, 데이터 변환은 다음과 같이 저장된다는 것을 잊지 마십시오.useRef는 재설정을 트리거하지 않습니다.그래서 길이를 변경해서 재연장을 하려면useState.

const Component = () => {

  const [length, setLength] = useState(2);
  const refs = useRef([React.createRef(), React.createRef()]);

  function updateLength({ target: { value }}) {
    setLength(value);
    refs.current = refs.current.splice(0, value);
    for(let i = 0; i< value; i++) {
      refs.current[i] = refs.current[i] || React.createRef();
    }
    refs.current = refs.current.map((item) => item || React.createRef());
  }

  useEffect(() => {
   refs.current[refs.current.length - 1].current.focus()
  }, [length]);

  return (<>
    <ul>
    {refs.current.map((el, i) =>
      <li key={i}><input ref={refs.current[i]} value={i} /></li>
    )}
  </ul>
  <input value={refs.current.length} type="number" onChange={updateLength} />
  </>)
}

또, 접속을 시도하지 말아 주세요.refs.current[0].current첫 번째 렌더링 - 오류가 발생합니다.

말합니다

      return (<ul>
        {['left', 'right'].map((el, i) =>
          <li key={i}>
            <input ref={refs.current[i]} value={el} />
            {refs.current[i].current.value}</li> // cannot read property `value` of undefined
        )}
      </ul>)

그러니까 넌 그걸 보호하거나

      return (<ul>
        {['left', 'right'].map((el, i) =>
          <li key={i}>
            <input ref={refs.current[i]} value={el} />
            {refs.current[i].current && refs.current[i].current.value}</li> // cannot read property `value` of undefined
        )}
      </ul>)

또는 에 액세스 합니다.useEffect후크. 이유:ref는 요소가 렌더링된 후에 바인딩되므로 렌더링 중에 처음 초기화되지 않습니다.

Skyboyer의 답변을 조금 더 자세히 말씀드리겠습니다.퍼포먼스 최적화(및 잠재적인 이상한 버그를 피하기 위해)에는useMemo대신useRefuseMemo는 값이 아닌 인수로 콜백을 받아들이기 때문에React.createRef첫 번째 렌더링 후에 한 번만 초기화됩니다.콜백 내에서는, 다음의 배열을 반환할 수 있습니다.createRef값 및 어레이를 적절하게 사용합니다.

초기화:

  const refs= useMemo(
    () => Array.from({ length: 3 }).map(() => createRef()),
    []
  );

빈 배열은 두 번째 인수로 React에 참조를 한 번만 초기화하도록 지시합니다.참조 카운트가 변경되면 합격해야 할 수 있습니다.[x.length]"a deps array"로 지정하여 동적으로 참조를 작성합니다.Array.from({ length: x.length }).map(() => createRef()),

사용방법:

  refs[i+1 % 3].current.focus();

부모 추천서를 가지고 아이들을 조종하다

const Component = () => {
  const ulRef = useRef(null);

  useEffect(() => {
    ulRef.current.children[0].focus();
  }, []);

  return (
    <ul ref={ulRef}>
      {['left', 'right'].map((el, i) => (
        <li key={i}>
          <input value={el} />
        </li>
      ))}
    </ul>
  );
};

저는 이렇게 일합니다.그것은 다른 제안보다 간단한 대답이라고 생각합니다.

참조 배열 등을 사용하는 대신 각 맵 항목을 구성 요소로 분리할 수 있습니다.따로따로따로따라서useRef는 독립적으로 사용할 수 있습니다.

const DATA = [
  { id: 0, name: "John" },
  { id: 1, name: "Doe" }
];

//using array of refs or something like that:
function Component() {
  const items = useRef(Array(DATA.length).fill(createRef()));
  return (
    <ul>
      {DATA.map((item, i) => (
        <li key={item.id} ref={items[i]}>
          {item.name}
        </li>
      ))}
    </ul>
  );
}


//seperate each map item to component:
function Component() {
  return (
    <ul>
      {DATA.map((item, i) => (
        <MapItemComponent key={item.id} data={item}/>
      ))}
    </ul>
  );
}

function MapItemComponent({data}){
  const itemRef = useRef();
  return <li ref={itemRef}>
    {data.name}
  </li>
}

이 예에서와 같이 배열의 길이를 미리 알고 있는 경우 참조 배열을 작성한 후 인덱스로 각 참조를 할당할 수 있습니다.

const Component = () => {
  const items = Array.from({length: 2}, a => useRef(null));
  return (
    <ul>
      {['left', 'right'].map((el, i)) => (
        <li key={el} ref={items[i]}>{el}</li>
      )}
    </ul>
  )
}

이와 같은 문제가 발생하여 'Joer'의 답변을 읽고 querySelector 클래스를 동적으로 설정하는 인덱스를 사용하여 전체 부모에 대해 하나의 참조만 설정할 수 있음을 깨달았습니다.코드 로딩에 대해 사과드립니다만, 이것이 도움이 되기를 바랍니다.

import React, { useRef, useState } from 'react';
import { connectToDatabase } from "../util/mongodb";

export default function Top({ posts }) {
  //const [count, setCount] = useState(1);
  const wrapperRef = useRef(null);


  const copyToClipboard = (index, areaNumber) => {
    // 
    // HERE I AM USING A DYNAMIC CLASS FOR THE WRAPPER REF 
    // AND DYNAMIC QUERY SELECTOR, THEREBY ONLY NEEDING ONE REF ON THE TOP PARENT
    const onePost = wrapperRef.current.querySelector(`.index_${index}`)
    const oneLang = onePost.querySelectorAll('textarea')[areaNumber];
    oneLang.select();
    document.execCommand('copy');
  };

  var allPosts = posts.map((post, index) => {

    var formattedDate = post.date.replace(/T/, ' \xa0\xa0\xa0').split(".")[0]
    var englishHtml = post.en1 + post.en2 + post.en3 + post.en4 + post.en5;
    var frenchHtml = post.fr1 + post.fr2 + post.fr3 + post.fr4 + post.fr5;
    var germanHtml = post.de1 + post.de2 + post.de3 + post.de4 + post.de5;

    return (
      <div className={post.title} key={post._id}>
        <h2>{formattedDate}</h2>
        <h2>{index}</h2>

        <div className={"wrapper index_" + index}>
          <div className="one en">
            <h3>Eng</h3>
            <button onClick={() => {copyToClipboard(index, 0)}}>COPY</button>
            <textarea value={englishHtml} readOnly></textarea>
          </div>

          <div className="one fr">
            <h3>Fr</h3>
            <button onClick={() => {copyToClipboard(index, 1)}}>COPY</button> 
            <textarea value={frenchHtml} readOnly></textarea>
          </div>

          <div className="one de">
            <h3>De</h3>
            <button onClick={() => {copyToClipboard(index, 2)}}>COPY</button>
            <textarea value={germanHtml} readOnly></textarea>
          </div>
        </div>

      </div>
    )
  })

  return (
    <div ref={wrapperRef}>
      <h1>Latest delivery pages </h1>
      <ul>
        {allPosts}
      </ul>

      <style jsx global>{`

        body{
          margin: 0;
          padding: 0;
        }
        h1{
          padding-left: 40px;
          color: grey;
          font-family: system-ui;
          font-variant: all-small-caps;
        }
        .one,.one textarea {
          font-size: 5px;
          height: 200px;
          width: 300px;
          max-width:  350px;
          list-style-type:none;
          padding-inline-start: 0px;
          margin-right: 50px;
          margin-bottom: 150px;
          
        }

        h2{
          font-family: system-ui;
          font-variant: all-small-caps;
        }
        .one h3 {
          font-size: 25px;
          margin-top: 0;
          margin-bottom: 10px;
          font-family: system-ui;
        }

        .one button{
          width: 300px;
          height: 40px;
          margin-bottom: 10px;
        }

        @media screen and (min-width: 768px){
          .wrapper{
            display: flex;
            flex-direction: row;
          }
        }

      `}</style>
    </div>
  );
}

이 경우 빈 참조 배열을 작성하고 React 구성 요소 내에서 생성되는 동안 참조를 푸시해야 합니다.

그런 다음 useEffect를 사용하여 해당 참조를 처리합니다.

다음은 예를 제시하겠습니다.

const refs = []

useEffect(() => {
    refs.map(ref => {
      console.log(ref.current)
      // DO SOMETHING WITH ref.current
    })
  }, [refs])

{postsData.map((post, i) => {
   refs.push(React.createRef())
   return (
     <div ref={refs[i]} key={post.id}>{...}</div>
   )}
}

언급URL : https://stackoverflow.com/questions/54940399/how-target-dom-with-react-useref-in-map

반응형