首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在滚动页面时使组件更改状态(响应)

在滚动页面时使组件更改状态(响应)
EN

Stack Overflow用户
提问于 2022-08-31 10:31:40
回答 1查看 55关注 0票数 0

我有一个单一的页面反应应用程序,它由几个部分组成,分成几个组成部分:

代码语言:javascript
复制
function App() {
  return (
    <div>
        <Langbar />
        <Header />
        <Nav />
        <About />
        <Education />
        <Experience />
        <Projects />
        <Contact />
        <Footer />
    </div>
  );
}

Nav组件是一个简单的导航栏,它使用useState在单击时更改链接的样式:

代码语言:javascript
复制
const Nav = () => {
  const [activeNav, setActiveNav] = useState('#');
  return (
    <nav>
        <a href="#" onClick={() => setActiveNav('#')} className={activeNav === '#' ? 'active' : ''}><HiHome /></a>
        <a href="#about" onClick={() => setActiveNav('#about')} className={activeNav === '#about' ? 'active' : ''}><HiUser /></a>
        <a href="#education" onClick={() => setActiveNav('#education')} className={activeNav === '#education' ? 'active' : ''}><FaGraduationCap /></a>
        <a href="#experience" onClick={() => setActiveNav('#experience')} className={activeNav === '#experience' ? 'active' : ''}><HiBriefcase /></a>
        <a href="#projects" onClick={() => setActiveNav('#projects')} className={activeNav === '#projects' ? 'active' : ''}><FaLaptopCode /></a>
        <a href="#contact" onClick={() => setActiveNav('#contact')} className={activeNav === '#contact' ? 'active' : ''}><HiMailOpen /></a>
    </nav>
  )
}

导航栏

我想改变样式的链接,不仅当我点击他们,而且当我滚动页面和相对部分(组件)进入视口。

我已经成功地连接了react库,并检测了组件何时进入viewport (并将消息记录到控制台),但不确定如何将此信息传递给Nav组件并根据其更改状态。

具有的About组件的代码:

代码语言:javascript
复制
require('intersection-observer');

const AboutRender = (props: { inViewport: boolean }) => {
  const { inViewport, forwardedRef } = props;
  const { t } = useTranslation();
  return (
    <section id="about" ref={forwardedRef}>
      <h2>{t("about.title")}</h2>

      <div className="container about__container">
        <div className="about__me">
          <div className="about__me-image">
            <img src={Me} alt="About image" />
          </div>
        </div>

        <div className="about__content">
          <h3>{t("about.summary")}</h3>
          <div className="about__content__text">
            <p>{t("about.summary_1")}</p>
            <p>{t("about.summary_2")}</p>
            <p>{t("about.summary_3")}</p>
            <p>{t("about.summary_4")}</p>
          </div>
          <h3>{t("about.tech_skills")}</h3>
          <div className="about__content__skills">
            <article className="skill__card">
              <SiHtml5 className="skill__icon"/>
              <h5>HTML</h5>
            </article>
            <article className="skill__card">
              <SiCss3 className="skill__icon"/>
              <h5>CSS</h5>
            </article>
            <article className="skill__card">
              <SiJavascript className="skill__icon"/>
              <h5>JavaScript</h5>
            </article>
            <article className="skill__card">
              <SiReact className="skill__icon"/>
              <h5>React, React Native</h5>
            </article>
            <article className="skill__card">
              <SiFigma className="skill__icon"/>
              <h5>Figma</h5>
            </article>
          </div>
        </div>
      </div>
    </section>
  )
}

const AboutWithRef = handleViewport(AboutRender  /** options: {}, config: {} **/);

const About = (props: {isInViewport: boolean}) => {
  const {isInViewport} = props;
  return(
    <AboutWithRef onEnterViewport={() => this.props.isInViewport=true} onLeaveViewport={() => console.log('leave')} />
  )
}

提前感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-31 10:53:38

因此,基本上您想要在两个组件之间共享信息,为了做到这一点,您应该进行状态提升,也就是说,两个组件之间的公共状态应该由它们的公共容器组件承载,在您的示例中,它的App组件,所以首先在app组件中定义状态来存储活动链接,然后像这样设置它

代码语言:javascript
复制
function App() {
 const [activeNav, setActiveNav] = useState('#');
return (
<div>
    <Langbar />
    <Header />
    <Nav />
    <About />
    <Education />
    <Experience />
    <Projects />
    <Contact />
    <Footer />
</div>
);}

然后把它传递给像这样的子组件

代码语言:javascript
复制
 <Nav setActiveNav={setActiveNav} activeNav={activeNav}/>
 <AboutRendersetActiveNav={setActiveNav} activeNav={activeNav}/>

现在,将您的Nav组件更改为使用setActiveNav和activeNav,如下所示

代码语言:javascript
复制
            const Nav = (props) => {
            const {activeNav, setActiveNav} = props;
                return (
                    <nav>
                        <a href="#" onClick={() => setActiveNav('#')} className={activeNav === '#' ? 'active' : ''}><HiHome /></a>
                        <a href="#about" onClick={() => setActiveNav('#about')} className={activeNav === '#about' ? 'active' : ''}><HiUser /></a>
                        <a href="#education" onClick={() => setActiveNav('#education')} className={activeNav === '#education' ? 'active' : ''}><FaGraduationCap /></a>
                        <a href="#experience" onClick={() => setActiveNav('#experience')} className={activeNav === '#experience' ? 'active' : ''}><HiBriefcase /></a>
                        <a href="#projects" onClick={() => setActiveNav('#projects')} className={activeNav === '#projects' ? 'active' : ''}><FaLaptopCode /></a>
                        <a href="#contact" onClick={() => setActiveNav('#contact')} className={activeNav === '#contact' ? 'active' : ''}><HiMailOpen /></a>
                    </nav>
                )
            }

现在您的about组件应该像这样设置链接

代码语言:javascript
复制
            const About = (props) => {
                const {setActiveNav}=props
                return(
                <AboutWithRef onEnterViewport={() => setActiveNav("#active")} />
                )
            }

因为在任何给定的时刻,您都将处于特定的视图中,因此不需要处理onLeaveViewport事件

希望这对在这里读更多有帮助

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73554557

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档