Boky
Boky

Reputation: 12084

Scroll in React JS

Is there any way to create an animation on scroll in a click event in React JS without JQuery?

I have a navigation and I want to go to a page section depending on what user is clicked. And I want to do it with some animation.

The problem is that the navigation and the section are not in the same file.

I have something like this in main component :

render() {
    return (
        <div>
            <Header currentLanguage={this.props.language.labels}/>
            {React.cloneElement(this.props.children, {
                currentLanguage: this.props.language.labels
            })}
            <Footer currentLanguage={this.props.language.labels}/>
        </div>
    );
}

In this props children are the sections which I want to navigate. They are :

return (
            <div className="homeMain">
                <section ref="home" className="marginOnXs">
                    <MainSlider />
                </section>
                <section id="performance" ref="performance">
                    <Performance currentLanguage={languageHome}/>
                </section>
                <section id="benefits" ref="benefits">
                    <Benefits currentLanguage={languageHome} />
                </section>
                 <section ref="contact" id="contact">
                        <ContactForm currentLanguage={languageHome}/>
                 </section>
            </div>
        );

Inside header I have something like this :

<ul className="noPadding">
     <li> <Link to="" onClick={this.handleScroll.bind(this, "home")}>Home </Link></li>
     <li> <Link to="" onClick={this.handleScroll.bind(this, "contact")}>Contact?</Link></li>
 </ul>

And in handle scroll I tried something like :

handleScroll(id, event){
    event.preventDefault();
    let test = ReactDom.findDOMNode(this.refs[id]);
    let scrollTop = event.target.body.scrollTop,
    itemTranslate = Math.min(0, scrollTop/3 - 60);
    window.scrollTo(0, itemTranslate);
}

But it won't work. this.refs[id] return undefined. If contact link in header get clicked the parameter id in the function is contact, but it can't find this.refs["contact"], because it is in some other component.

Any advice?

Upvotes: 0

Views: 2120

Answers (2)

Rahul Kumar
Rahul Kumar

Reputation: 17

You can use one of the react libraries React Reveal. You can wrap your components in these tags and they will animate while scrolling.

For example :

<Zoom>
  <p>Markup that will be revealed on scroll</p>
</Zoom>

Go through the documentation to see all the different ways to reveal while scrolling.

You can also see demos Here

Upvotes: 0

jssridhar
jssridhar

Reputation: 458

You can use props to pass down functions and use as a means to communicate between sibling components.

You can use "this.props.handleScroll" and in your root component and pass on the id to scroll to to the children. Something like,

    <ul className="noPadding">
      <li> <Link to="" onClick={this.props.handleScroll.bind(this, "home")}>Home </Link></li>
      <li> <Link to="" onClick={this.props.handleScroll.bind(this, "contact")}>Contact?</Link></li>
    </ul>

   <-- In your root component --->
    <Header currentLanguage={this.props.language.labels} handleScroll={::this.handleScroll}} />

    handleScroll(id, event) {
      this.setState({
        scrollToId: id
      })
    }

    render() {
        return (
            <div>
                <Header currentLanguage={this.props.language.labels}/>
                {React.cloneElement(this.props.children, {
                    currentLanguage: this.props.language.labels,
                    scrollToId: this.state && this.state.scrollToId
                })}
                <Footer currentLanguage={this.props.language.labels}/>
            </div>
        );
    }

    <-- In your child component -->

    componentDidUpdate() {
      const idToScroll = this.props.scrollToId;
      // you can access this.refs[idToScroll] here and get the 
      // scrollheight and scroll to the position of the element
    }

    return (
          <div className="homeMain">
              <section ref="home" className="marginOnXs">
                  <MainSlider />
              </section>
              <section id="performance" ref="performance">
                  <Performance currentLanguage={languageHome}/>
              </section>
              <section id="benefits" ref="benefits">
                  <Benefits currentLanguage={languageHome} />
              </section>
               <section ref="contact" id="contact">
                      <ContactForm currentLanguage={languageHome}/>
               </section>
          </div>
    );

I think you should go through this to get a better idea for communicating between components, React.js - Communicating between sibling components and the answer to React.js - Communicating between sibling components

Upvotes: 1

Related Questions