The KNVB
The KNVB

Reputation: 3844

How to prevent the "Warning: findDOMNode is deprecated in StrictMode" from setState method

This is my code:

import Card  from 'react-bootstrap/Card';
import Collapse from 'react-bootstrap/Collapse';
import React from 'react';
import MuteButton from './buttons/muteButton/MuteButton';
import PInPButton from "./buttons/pInPButton/PInPButton";
import Utility from '../../Utility';
import './MediaPlayer.css'
class MediaPlayer extends React.Component {
    
    constructor(props) {
        super(props);
        this.playerOverlay =React.createRef();
        this.videoTag = React.createRef();
        this.state={ muted:true, elapseTime:"00:00:00",showControlBar:true};
        this.setCurrentTime=((currentTime)=>{
            this.videoTag.current.currentTime=currentTime;
        });
        this.setStream=((stream)=>{
            this.videoTag.srcObject=null;
            this.videoTag.srcObject=stream;
        });
       
    }
    toggleControlBar=(obj)=>{
            
    };
    toggleMute = () => {
        this.setState({
          muted: !this.state.muted
        });
    };
    togglePInP=(()=>{

    })    
    componentDidMount(){
        this.videoTag.ontimeupdate=(()=>{
            var result=Utility.toHHMMSS(this.videoTag.currentTime);
            this.setState({"elapseTime":result});
        });
        
        this.playerOverlay.onclick=((event)=>{
            if (event.target.classList.contains("playerOverlay")){
                this.setState((state) => ({
                    showControlBar: !state.showControlBar
                }));
                //this.setState({showControlBar:!this.state.showControlBar});
            }
        });        
    }
    
    render() {
        return (
            <Card className="h-100 rounded">
                <video 
                    autoPlay 
                    muted={this.state.muted}
                    className="card-body p-0 rounded w-100"
                    ref={(instance) => (this.videoTag = instance)}>
                        <source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"></source>
                </video>
                <div 
                    className="align-items-center 
                        justify-content-center 
                        playerOverlay
                        text-white"
                        >
               </div>
                <div className="p-1 
                                justify-content-end 
                                playerOverlay
                                rounded"
                    ref={(instance) => (this.playerOverlay = instance)}>
                  <Collapse in={this.state.showControlBar} 
                    className="bg-secondary p-1 rounded text-white w-100 ">
                    <div className="p-0 m-0">
                        <div className="align-items-center d-flex flex-row justify-content-between p-0">
                            <MuteButton toggleMute={this.toggleMute}  muted={this.state.muted}/>
                            <div><span>{this.state.elapseTime}</span></div>
                        </div>
                        <div className="align-items-center d-flex flex-row justify-content-between p-0">
                            <PInPButton togglePInP={this.togglePInP}/>
                        </div>
                    </div>
                  </Collapse>
                </div>    
            </Card>     
        );
    }    
}
export default MediaPlayer;    

The problem is that when the following event handler is executed,

this.playerOverlay.onclick=((event)=>{
        if (event.target.classList.contains("playerOverlay")){
            this.setState((state) => ({
                showControlBar: !state.showControlBar
            }));
            //this.setState({showControlBar:!this.state.showControlBar});
        }
    });        

The following warning message is shown in the console:

index.js:1 Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of Transition which is inside StrictMode. 

I found that the "this.setState" function caused the error.

I have tried to modify the above code to remove the warning, however, it does not work.

I have followed here to change the below coding:

ref={(instance) => (this.playerOverlay = instance)}>

to

 ref={this.playerOverlay}>

However, still no luck.

How can I fix the problem?

Upvotes: 1

Views: 1294

Answers (2)

Daniel Arenas
Daniel Arenas

Reputation: 13

According to Pramod, you only need to create a new childComponent with react.forwardRef passing respective props and refs:

const ChildComponent = React.forwardRef((props, ref) =>
  <div ref={ref}>
    <yourChildcomponent {...props} />
  </div>

In your render change the name of the original Child for the new:

<ChildCompoent... />

Upvotes: 0

Pramod Mali
Pramod Mali

Reputation: 1808

findDOMNode is deprecated in StrictMode. Its usage is discouraged and, possibly, it will be deleted in a future version. Still, there are ways to overcome this with alternatives.

Of course, we should not remove the StrictMode as it may introduce other potential issues.

  1. Add DOM node wrapper
...
componentDidMount() {
      const node = this.wrapper.current;
      /* Uses DOM node  */ 
}
wrapper = React.createRef();

render(){
 ...
  <div ref={this.wrapper}>
     ...
  </div>
 ...
}
  1. Ref forwading

Wrap child component in React.forwardRef(props,ref)

const ChildComponent = React.forwardRef((props, ref) =>
  <div ref={ref}>
    ...
  </div>
);
  1. Using HOC(Higher Order components)

Here are a couple of posts that maybe useful for this.

https://medium.com/trabe/getting-rid-of-finddomnode-method-in-your-react-application-a0d7093b2660

https://medium.com/trabe/a-better-way-of-using-refs-in-react-dd970d2b13e5

Upvotes: 1

Related Questions