简体   繁体   中英

findDOMNode is deprecated in StrictMode. Warning - react-transition-group + react v17 + Javascript (Not Typescript)

I'm trying to get rid of a warning message in the project I'm working on.

index.js:1 Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of Transition which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-find-node
    at div
    at Transition (http://localhost:3000/static/js/vendors~main.chunk.js:47483:30)
    at CSSTransition (http://localhost:3000/static/js/vendors~main.chunk.js:46600:35)
    at div
    at TransitionGroup (http://localhost:3000/static/js/vendors~main.chunk.js:48052:30)
    at Contacts (http://localhost:3000/static/js/main.chunk.js:1623:96)
    at div
    at div
    at Home (http://localhost:3000/static/js/main.chunk.js:2549:88)
    at AuthCheck (http://localhost:3000/static/js/main.chunk.js:2705:5)
    at Routes (http://localhost:3000/static/js/vendors~main.chunk.js:45749:5)
    at div
    at Router (http://localhost:3000/static/js/vendors~main.chunk.js:45682:15)
    at BrowserRouter (http://localhost:3000/static/js/vendors~main.chunk.js:45198:5)
    at ContactState (http://localhost:3000/static/js/main.chunk.js:3743:85)
    at AuthState (http://localhost:3000/static/js/main.chunk.js:3243:85)
    at AlertState (http://localhost:3000/static/js/main.chunk.js:2844:85)
    at App

The problematic code:

import React, { Fragment, useEffect } from 'react';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import { useContactContext } from '../../context/contact/contactContext';
import { useAuthtContext } from '../../context/auth/authContext';

import ContactItem from './ContactItem';
import Spinner from '../layout/Spinner';

const Contacts = () => {
    const { contacts, filtered, getContacts, loading } = useContactContext();
    const { isAuthenticated } = useAuthtContext();

    useEffect(() => {
        if (isAuthenticated) {
            getContacts();
        }
        // eslint-disable-next-line
    }, [isAuthenticated]);

    if (!loading && contacts !== null && contacts.length === 0) {
        return <h4>Please add a contact</h4>;
    }

    return (
        <Fragment>
            {contacts === null || loading ? (
                <Spinner />
            ) : (
                <TransitionGroup>
                    {(filtered || contacts).map((contact) => (
                        <CSSTransition timeout={1000} classNames="item" key={contact._id}>
                            <ContactItem contact={contact} />
                        </CSSTransition>
                    ))}
                </TransitionGroup>
            )}
        </Fragment>
    );
};

export default Contacts;

I've spent a few hours looking for answers, but I feel like I'm running around in an endless loop.

To get rid of the warning, I need to use useRef hooks on each CSSTransition element, to connect it with (it's children?).

I can't use useRef() inside the render function of a component, so I defined a new component to display each TransitionItem :

...
        const TransitionItem = ({ contact, ...props }) => {
            const ref = useRef(null); // Had to use this ref to go around a warning
            return (
                <CSSTransition nodeRef={ref} timeout={1000} classNames="item" {...props}>
                    <div ref={ref}>
                        <ContactItem contact={contact} />
                    </div>
                </CSSTransition>
            );
        };
    
        return (
            <Fragment>
                {contacts === null || loading ? (
                    <Spinner />
                ) : (
                    <TransitionGroup>
                        {(filtered || contacts).map((contact) => (
                            <TransitionItem key={contact._id} contact={contact} />
                        ))}
                    </TransitionGroup>
                )}
            </Fragment>
        );
...

Now every time I try to click on a button, to remove an item from the list, I see a "flashing" effect, you can check out in this Sandbox: (Click on the red buttons to remove an item) https://codesandbox.io/s/kind-feather-2psuz

The "flashing" problem only starts when I move the CSSTransition component into the new TransitionItem component, but I can't use useRef hooks on each item if I don't move it there.

Help pls: :)

PS:

  1. Removing <React.StrictMode> from the index.js is not a solution to the root problem.

I have the same warning in my project and i can fix it with this solution, thank pixel-fixer !

Issue #668 on repo react-transition-group

From 4.4.0 release notes:

react-transition-group internally uses findDOMNode, which is deprecated and produces warnings in Strict Mode, so now you can optionally pass nodeRef to Transition and CSSTransition, it's a ref object that should point to the transitioning child:

You can fix this like this

import React from "react"
import { CSSTransition } from "react-transition-group"

const MyComponent = () => {
  const nodeRef = React.useRef(null)
  return (
    <CSSTransition nodeRef={nodeRef} in timeout={200} classNames="fade">
      <div ref={nodeRef}>Fade</div>
    </CSSTransition>
  )
}

I hope it works for you, have a nice day !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM