Add scrollbar to a Box

3

I am in doubt about my code, in it I will add a chat field, and in this chat the box must have a maximum size, and if in this case when adding the messages exceeds this value, it should create a scroll bar, but this is not working.

In the browser I make these errors: TypeError: Can not read property 'scrollHeight' of null

> 43 | ReactDOM.findDOMNode (this.refs.data) .scrollTop = ReactDOM.findDOMNode (this.refs.data) .scrollHeight;

Follow the code below:

import React, {Component} from 'react';
import './Chat.css';
import { If, Then, Else } from 'react-if';
import ReactDOM from 'react-dom';
import Message from './Message.js';

class Chat extends React.Component {

  constructor(props) {
        super(props);

        this.state = {
          data:[],
            chats: [] };

        this.submitMessage = this.submitMessage.bind(this);
    }

componentDidMount(){
        let URL = 'stackTeste'

           fetch(URL)
           .then(function(response) {
              let data = response.json()
              return data;
           })
           .then((json) => {
              console.log('Vetor JSON: ', json)
              this.setState({data : json});
           })
           .catch(function(ex) {
              console.log('parsing failed', ex)
           })
           this.scrollToBot();
  }


  componentDidUpdate() {
          this.scrollToBot();
      }

      scrollToBot() {
          ReactDOM.findDOMNode(this.refs.data).scrollTop = ReactDOM.findDOMNode(this.refs.data).scrollHeight;
      }


  submitMessage(e) {
      e.preventDefault();

      this.setState({
          chats: this.state.chats.concat([{
              username: "Eu",
              content: <p>{ReactDOM.findDOMNode(this.refs.msg).value}</p>,
              img: "https://www.sitelovers.com.br/franquias/2/0e01938fc48a2cfb5f2217fbfb00722d/36452e720502e4da486d2f9f6b48a7bb/editor/image/circulo_laranja.png",
              time: "1 min ago",
          }])
      }, () => {
          ReactDOM.findDOMNode(this.refs.msg).value = "";
      });
  }


render(){
  const username = "Kevin su";
        const { chats } = this.state;
    return(
    <div className="container">
        <div className="chatroom ">
           <div className="box-header with-border" >
           <i className="fa fa-commenting-o fa-2x">  </i>
               <h3 className="box-title">Chat</h3>
           </div>
           {
                 this.state.data.map((obj) =>
                  <div className="box-body">
                      <div className="direct-chat-msg undefined">
                          <div className="direct-chat-info clearfix">
                  </div>
                      <If condition={obj.displayPortraitLeft == true}>
                      <Then>
                            <div className="direct-chat-info clearfix">
                              <span className="direct-chat-name pull-left">{obj.userName}</span>
                              <span className="direct-chat-timestamp pull-left">{obj.time}</span>
                            </div>
                              <img className="direct-chat-img" src={obj.portrait} alt="message user image"/>
                      </Then>
                      <Else>
                            <div nameClass="direct-chat-msg right">
                                <div className="direct-chat-info clearfix">
                                    <span className="direct-chat-name pull-right">{obj.userName}</span>
                                    <span className="direct-chat-timestamp pull-right">{obj.time}</span>
                                </div>
                                    <img className="direct-chat-img-right" src={obj.portrait} alt="message user image"/>
                            </div>
                      </Else>
                      </If>
                      <div className="direct-chat-text">{obj.message}</div>

                  </div>
                  </div>
                 )

             }
             {
                                  chats.map((chat) =>
                                  <div className="box-body">
                                      <div className="direct-chat-msg undefined">
                                          <div className="direct-chat-info clearfix">
                                  </div>
                                     <Message chat={chat} user={username} />
                                     </div>
                                     </div>
                                                )
                                      }
              <div className="input-group">
                            <form onSubmit={(e) => this.submitMessage(e)}>
                                 <input type="text" ref="msg" className="form-control"/>
                                 <span className="input-group-btn">
                                 <input type="submit" className="btn btn-flat btn-primary" value="Submit" />
                                 </span>
                             </form>
                             </div>
    </div>
  </div>
    );
  }
}
export default Chat;
    
asked by anonymous 23.11.2017 / 09:59

1 answer

0

These are some of the causes of returning this error:

  • The element was not rendered
  • The given reference is not the same as the element, for example:

    <div ref="box">
    

    When you redeem the item:

    ReactDOM.findDOMNode(this.refs.boxx)
    

    or the other way around.

  • The correct thing is to check if the element was rendered and / or if the reference is right:

    scrollToBot() {
        const check= ReactDOM.findDOMNode(this.refs.data);
        if (check) {
            check.scrollTop = check.scrollHeight;
        }
    }
    

    For example, I created two projects, they are simple, just an object containing some text and a button, which when clicking moves the scroll of block box .

    class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          mensagens: [
            'Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem',
            'Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem',
            'Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem',
            'Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem','Mensagem',
          ]
        };
        this.moverScroll = this.moverScroll.bind(this);
      }
      moverScroll(event) {
        // Abaixo verificamos se a div 'box' foi renderizada
        // Caso tenha sido, move o scroll para baixo
        const check = ReactDOM.findDOMNode(this.refs.box);
        if (check){
          check.scrollTop = check.scrollHeight;
        }
      }
      render() {
        return(
          <div>
            <div ref="box" style={styles.box}>
              {this.state.mensagens.map((msg, i) => (
                <p style={styles.msg} key={i}>{msg} {i}</p>
              ))}
            </div>
            <button onClick={this.moverScroll}>CLIQUE PARA MOVER O SCROLL</button>
          </div>
        )
      }
    }
    
      

    You can see working Example with verification and Example without verification .

        
    04.02.2018 / 00:32