Реакция createRef, возвращающая current = null при создании динамически генерируемых компонентов c - PullRequest
0 голосов
/ 27 марта 2020

У меня есть компонент React, который получает объект со свойствами для динамического создания некоторых дочерних компонентов. При создании этих новых компонентов мне нужно создать ссылку для каждого из них, но React.createRef() возвращает current как null.

Вот что я сделал:

const source = {
   component1: {
      name: 'Component 1',
      active: true
   },
   component2: {
      name: 'Component 2',
      active: true
   },
   component3: {
      name: 'Component 3',
      active: false
   }
}

тогда это основной компонент:

function MyComp(props) {
   const {source} = props;

   const refs = {};

   function makeComps() {
      const newComps = [];
      Object.keys(source).forEach(x => {
         const myRef = React.createRef();
         refs[x] = myRef;
         newComps.push(
         <div ref={myRef}>
           <div>Name</div>
           <div>{source[x].name}</div>

           <div>Active</div>
           <div>{source[x].active ? 'Yes' : 'No'}</div>
         </div>);
      });
      return newComps;
   }

   return (
      <>
        <strong>{'Brand new components'}</strong>
        {source && makeComps()}
        {!source && <div>Nothing new</div>}
      </>
   );
}

Затем, когда я пытаюсь получить доступ к refs, возвращается:

{
   component1: {current: null},
   component2: {current: null},
   component3: {current: null}
}

Мне нужны эти ссылки для создания window.scrollTo при некоторых условиях. Согласно официальной документации React, я не делаю ничего странного. Также я попробовал с React.useRef() вместо этого, но ничего.

Вот как я получаю эти ссылки:

const myRef = refs.component3;
window.scrollTo({ behavior: 'smooth', top: myRef.current.offsetTop });

Как я могу решить эту проблему? Что мне здесь не хватает?

Ответы [ 2 ]

1 голос
/ 28 марта 2020

Я предполагаю, что вы пытаетесь получить к ним доступ до того, как был сделан первый рендер. В этом случае ваш компонент не смонтировал . Будьте уверены, используя крючок useEffect. Узнайте больше здесь .

function MyComp({ source, ...props }) {
  const refs = {};

  function makeComps() {
    const newComps = [];

    Object.keys(source).forEach((x, idx) => {
      const myRef = React.createRef();
      refs[x] = myRef;

      newComps.push(
        <div key={idx} ref={myRef}>
          <div>Name</div>
          <div>{source[x].name}</div>
          <div>Active</div>
          <div>{source[x].active ? 'Yes' : 'No'}</div>
        </div>
      );
    });

    return newComps;
  }

  useEffect(() => {
    // here, your component did mount

    // try to access component1 using the optional
    // chaining feature of JavaScript
    console.log(refs.component1?.current);
  }, [refs]);

  return (
    <>
      <strong>{'Brand new components'}</strong>
      {source && makeComps()}
      {!source && <div>Nothing new</div>}
    </>
  );
}
0 голосов
/ 28 марта 2020

Ну, Клуддиз здесь частично дал мне решение, хотя его решение не дает правильного ответа на мою проблему, он указал мне на правильное решение. Крючки для спасения:

useEffect(() => {
   if (refs.component3 && refs.component3.current) {
      //do the magic
   }
});

Его комментарий:

Вы должны быть уверены, что получите доступ к ссылкам после первого рендера. Это просто, потому что React не разрешает ссылки во время первого рендера.

была точкой входа в правильное решение.

...