2

So the main aim of me using refs is so that I can reset the scroll position of a scrollable div, this is an image of the div before adding content this is how it looks before dynamically adding divs to the scrollable container div

This is a screenshot of the div after adding boxes to it: the box is created outside of viewport and is created at the top of the scrollable area

So to be able to maintain the viewport at the top of the scrollable area I am hoping to use refs to do ReactDOM.findDOMNode(this.songIdWrapper) and then manipulate the scrollTop or use scrollTo methods.

Please find the code snippet below:

import React, {Component} from 'react';
import ReactDOM from 'react-dom';

class AddPlaylist extends Component {
    constructor(props){
        super(props);
        this.state = {
            displaySearch: false,
            id: '',
            playlistName:'',
            playlistTitle:'',
            songs:[]
        }

        this.handleIdSubmit = this.handleIdSubmit.bind(this);
        this.handleIdChange = this.handleIdChange.bind(this);
        this.handleNamechange = this.handleNamechange.bind(this);
        this.handleNameSubmit= this.handleNameSubmit.bind(this);
        this.callback=this.callback.bind(this);
    }
    componentWillUpdate () {
        console.log(ReactDOM.findDOMNode(this.songIdWrapper));
    }
    componentDidUpdate () {
        
    }

    callback (songId) {
        this.songIdWrapper=songId;
    }
    render () {
        return(
            <div className='add-playlist-wrapper'> 
                <div className='form-wrapper container'>
                    <form onSubmit={this.handleNameSubmit} className='playlist-name-wrapper'>
                            <input className={this.state.submittedName ? 'hide-input' : ''} required onChange={this.handleNamechange} value={this.state.playlistName} placeholder='Playlist title'/>
                            {this.state.submittedName ? <p className='title'>{this.state.playlistTitle}</p> : null}
                    </form>
                    <form onSubmit={this.handleIdSubmit} className='add-id-wrapper'>
                        <div className='input-add-playlist'>
                            <input required onChange={this.handleIdChange} value={this.state.id} placeholder='Add song...'/>
                            <button type='submit' className='fabutton'>
                                <i className="add-button fa fa-plus-square-o fa-3x" aria-hidden="true"></i>
                            </button>
                        </div>
                    </form>
                    <div id='song-id-wrapper' ref={this.callback}>
                    {this.state.songs.map((song, i) => {
                        return (<div key={i} className='song'>
                                    <p>{song}</p>
                                </div>
                        )
                    })}
                </div>
                </div>
            </div>
        )
    }

    handleIdSubmit (event) {
        event.preventDefault();
        const newState = this.state.songs.slice();
        newState.push(this.state.id);
        this.setState({
            songs:newState
        })
    }

    handleIdChange (event) {
        this.setState({
            id: event.target.value
        })
    }

    handleNamechange (event) {
        this.setState({
            playlistName: event.target.value
        })
    }

    handleNameSubmit (event) {
        event.preventDefault();
        this.setState({
            playlistTitle: this.state.playlistName
        })
    }

}

export default AddPlaylist;

The error message I get is: this is the error message stating that ref is not a prop

So I am quite new to react and as far as I'm aware this is an attribute on a div element not passed as a prop to a component. So I hope you can see my confusion as when I search google/stack-overflow I see a lot of comments relating to child components. I am fully aware string refs have been depreciated and that callbacks should be used but no matter what I try I cannot get rid of this error message.

Any help would be greatly appreciated.

R.Thompson
  • 141
  • 1
  • 12

1 Answers1

0

I guess the issue is that you try to access the ref in the componentWillUpdate Hook. Because from the pure setup there is nothing wrong.

The componentWillUpdate Hook gets actually called before the next render cycle, which means you access the ref BEFORE your component gets rendered, which means that you always access the ref from the render cycle before. The ref gets updated with the next render cycle.

https://developmentarc.gitbooks.io/react-indepth/content/life_cycle/update/tapping_into_componentwillupdate.html

I think you should do the scroll position handling AFTER the component did update, not before it will update!

larrydahooster
  • 4,114
  • 4
  • 40
  • 47
  • I have tried the findDOMNode with the ref in componentdidMount and componentDidUpdate and I still get the same warning. I thought about what you said and have been playing around with a few of the lifecycle hooks. – R.Thompson Nov 24 '17 at 10:41