Как можно передать массив ссылок (Refs) из одного компонента в другой?

У вас есть компонент `Component1`, в котором вы используете массив ссылок `Refs` при помощи `useRef([])`. Вы пытаетесь передать этот массив в другой компонент, однако возникает ошибка: "Cannot read properties of undefined (reading 'current')". Как можно решить эту проблему? <br/> <code class="javascript">const sectionRefs = useRef([]);</code> <br/> <br/> <pre><code class="javascript">&lt;ScrollToNextSection visibleSection={visibleSection} ref={sectionRefs} /&gt;</code></pre> <br/> <pre><code class="javascript">import { useState, useRef, forwardRef } from "react";
import "./ScrollToNextSection.css";

function ScrollToNextSection() {
  const ScrollToSection = ({ visibleSection, ref }) =&gt; {
    const currentIndex = ref.current.findIndex(
      (ref) =&gt; ref &amp;&amp; ref.id === visibleSection
    );
    const nextSection = ref.current[currentIndex + 1];

    if (nextSection) {
      nextSection.scrollIntoView({ behavior: "smooth" });
      return;
    }

    ref.current[0].scrollIntoView({ behavior: "smooth" });
  };

  return (
    &lt;button onClick={ScrollToSection} className="scroll-btn"&gt;
      Вниз
    &lt;/button&gt;
  );
}
export default ScrollToNextSection;</code></pre>
  • 2 ноября 2024 г. 19:22
Ответы на вопрос 2
Чтобы передать массив ссылок (Refs) из одного компонента в другой, вы можете использовать `forwardRef` в React. При этом важно правильно использовать `ref`, который передается в дочерний компонент. В вашем коде есть несколько моментов, которые нуждаются в исправлении.

Вот шаги, которые нужно выполнить:

1. **Измените структуру `ScrollToNextSection` и используйте `forwardRef`:** Это позволит вам передавать `ref` из родительского компонента в дочерний.
  
2. **Убедитесь, что `ref` инициализируется правильно в `Component1`.** Лучше всего присваивать `ref` массиву с помощью `useRef` непосредственно в `Component1`.

Вот переписанный пример вашего кода с исправлениями:

### Component1.js
```javascript
import React, { useState, useRef } from "react";
import ScrollToNextSection from "./ScrollToNextSection";

function Component1() {
  const sectionRefs = useRef([]);

  // Добавьте рефы в массив в зависимости от ваших секций
  const sections = ['section1', 'section2', 'section3']; // Пример
  sections.forEach((section, index) => {
    sectionRefs.current[index] = React.createRef();
  });

  // Обработка видимости секции или других логик
  const [visibleSection, setVisibleSection] = useState(sections[0]);

  return (
    <div>
      {sections.map((section, index) => (
        <div key={section} ref={sectionRefs.current[index]} id={section}>
          {section}
        </div>
      ))}
      <ScrollToNextSection visibleSection={visibleSection} ref={sectionRefs} />
    </div>
  );
}

export default Component1;
```

### ScrollToNextSection.js
```javascript
import React, { forwardRef } from "react";
import "./ScrollToNextSection.css";

const ScrollToNextSection = forwardRef(({ visibleSection }, ref) => {
  const scrollToSection = () => {
    const currentIndex = ref.current.findIndex(
      (ref) => ref && ref.current.id === visibleSection
    );
    const nextSection = ref.current[currentIndex + 1];

    if (nextSection) {
      nextSection.current.scrollIntoView({ behavior: "smooth" });
      return;
    }

    if (ref.current[0]) {
      ref.current[0].current.scrollIntoView({ behavior: "smooth" });
    }
  };

  return (
    <button onClick={scrollToSection} className="scroll-btn">
      Вниз
    </button>
  );
});

export default ScrollToNextSection;
```

### Что было сделано:
- В `ScrollToNextSection` мы использовали `forwardRef` для приема `ref` из родительского компонента.
- Мы использовали `React.createRef()` для создания ссылок на каждый элемент секции.
- Мы обеспечили корректное использование `ref` и добавили проверки, чтобы избежать ошибок при попытке доступа к `current`.

Теперь ваш компонент должен работать без ошибок и корректно обрабатывать скролл к следующей секции.
Попробуйте вот так: 
import { useState, useRef, forwardRef } from "react";
import "./ScrollToNextSection.css";

const ScrollToNextSection = forwardRef(({ visibleSection }, ref) => {
  const scrollToSection = () => {
    const currentIndex = ref.current.findIndex(
      (sectionRef) => sectionRef && sectionRef.id === visibleSection
    );
    const nextSection = ref.current[currentIndex + 1];

    if (nextSection) {
      nextSection.scrollIntoView({ behavior: "smooth" });
    } else if (ref.current[0]) {
      ref.current[0].scrollIntoView({ behavior: "smooth" });
    }
  };

  return (
    <button onClick={scrollToSection} className="scroll-btn">
      Вниз
    </button>
  );
});

export default ScrollToNextSection;
Похожие вопросы