【问题标题】:Passing refs from Component to Component in React在 React 中将 ref 从一个组件传递到另一个组件
【发布时间】:2020-12-06 22:33:11
【问题描述】:

所以我不确定传递 refs 是否是最好的选择,但这就是我打算做的事情,告诉我是否有更好的选择..

所以我想要一个导航链接的 onClick,向下滚动到 div“contactForm”。

App.js

import ContactForm from './components/ContactForm'
import ParllaxPage from './components/ParllaxPage'
import NavigationBar from './components/NavigationBar'
import React from 'react';
import './App.css';

const App = () => {


  return (

    < div cssClass="App" >
      <body>
        <span><NavigationBar /></span>
        <ParllaxPage cssClass="parallax-wrapper" />
        <ParllaxPage cssClass="parallax-wrapper parallax-pageOne" />
        <ContactForm />
      </body >
    </div >
  );
}

export default App;

我试图使用 forwardRef,但我不确定我是否正确地这样做了......

导航栏.js

import ContactForm from "./ContactForm";
import React, { useRef } from "react";
import App from "../App";
import { Nav, Navbar, Form, FormControl, Button } from "react-bootstrap";

const ContactFormRef = React.forwardRef((props, ref) => (
 <ContactForm className="contactForm" ref={ref}>
  {props.children}
 </ContactForm>
));

const scrollToRef = (ref) => ref.current.scrollIntoView({ behavior: "smooth" });

const NavigationBar = () => {
 const ref = React.forwardRef(ContactFormRef);

 return (
  <Navbar bg="light" expand="lg">
   <Navbar.Brand href="#home">A1 Gutters</Navbar.Brand>
   <Navbar.Toggle aria-controls="b casic-navbar-nav" />
   <Nav className="mr-auto">
    <Nav.Link href="#home">Home</Nav.Link>
    <Nav.Link href="#link">Link</Nav.Link>
    <Nav.Link href="#" onClick={console.log(ref)}>
     Contact
    </Nav.Link>
   </Nav>
  </Navbar>
 );
};

export default NavigationBar;

我不认为真的需要显示其他文件,我只是想从 ContactForm 组件中取出 className,以便我可以在 onClick 上滚动到它。我目前在 onClick 中只有一个 console.log .

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    使用Hooks 将在此处简化。

    1. 拥有gotoContact 的状态变量和contactRef 的引用
    2. 为导航链接添加点击处理程序contact
    3. 添加 useEffect 钩子,并在使用时单击联系人并且 ref 可用(ref.current 中的值)然后调用滚动查看)
    import ContactForm from "./components/ContactForm";
    import ParllaxPage from "./components/ParllaxPage";
    import React, { useState, useEffect, useRef } from "react";
    import "./App.css";
    
    const NavigationBar = ({ onClickContact }) => {
      return (
        <Navbar bg="light" expand="lg">
          <Navbar.Brand href="#home">A1 Gutters</Navbar.Brand>
          <Navbar.Toggle aria-controls="b casic-navbar-nav" />
          <Nav className="mr-auto">
            <Nav.Link href="#home">Home</Nav.Link>
            <Nav.Link href="#link">Link</Nav.Link>
            <Nav.Link href="#" onClick={() => onClickContact()}>
              Contact
            </Nav.Link>
          </Nav>
        </Navbar>
      );
    };
    
    const App = () => {
      const [gotoContact, setGotoContact] = useState(false);
      const contactRef = useRef(null);
    
      useEffect(() => {
        if (gotoContact && contactRef.current) {
          contactRef.current.scrollIntoView();
          setGotoContact(false);
        }
      }, [gotoContact, contactRef.current]);
    
      return (
        <div cssClass="App">
          <body>
            <span>
              <NavigationBar onClickContact={() => setGotoContact(true)} />
            </span>
            <ParllaxPage cssClass="parallax-wrapper" />
            <ParllaxPage cssClass="parallax-wrapper parallax-pageOne" />
            <div ref={contactRef}>
              <ContactForm />
            </div>
          </body>
        </div>
      );
    };
    
    export default App;
    

    【讨论】:

    • 谢谢,我可以在点击时完成这项工作,但它并不能真正“滚动”,但我确信我可以修复这些问题,导航栏消失了,但这就是是的,我能想出办法。谢谢!
    【解决方案2】:

    你没有渲染 ContactFormRef,所以参考点什么都没有!

    App.js 应该是这样的:

    ...
    const App = () => {
      const myNestedRefRef=React.useRef();
      return (
        ...
          <NavigationBar contactRef={myNestedRefRef}/>
        ...
          <ContactForm ref={myNestedRefRef} />
        ...
      );
    }
    ...

    ContactForm.js

    ...
    function ContactForm=React.forwardRef((props, ref) => (
     <form ref={ref}>
      ...
     </form>
    ));

    导航栏.js

    const NavigationBar = ({contactRef}) => {
     return (
      ...
        <Nav.Link href="#" onClick={console.log(contactRef)}>
      ...
     );
    };

    考虑一下

    如果 &lt;ContactForm/&gt; 尚未渲染,则 ref 看起来像 {current:null}

    【讨论】:

      【解决方案3】:

      无需创建单独的ContactFormRef 包装器。只需在ContactForm 本身中使用React.forwardRef。那些没有通过 ref 的人不必知道它转发 refs。

      然后,记得将接收到的 ref 进一步传递给原生元素,或者使用 useImperativeHandle 钩子向其添加方法,而无需进一步向下传递。

       const ref = React.forwardRef(ContactFormRef)
      

      这是错误的。

      你应该和原生组件一样做:

      const ref = useRef()
      
      return <ContactForm ref={ref} >
          // etc
      </ContactForm>
      

      【讨论】:

        【解决方案4】:

        你应该用一个 id 来识别 div "contactForm" 并有一个锚标记指向它:

        <a href="#contactForm"></a>
        <div id="contactForm"></div>
        

        您可以在 CSS 中将 scroll-behaviour: smooth 添加到正文中

        【讨论】:

          猜你喜欢
          • 2022-08-17
          • 2018-05-07
          • 2021-04-16
          • 2021-01-11
          • 1970-01-01
          • 2021-08-11
          • 2021-01-02
          • 2021-10-31
          相关资源
          最近更新 更多