findDOMNode est obsolète dans StrictMode comment utiliser les refs à la place

Sep 01 2020

Salut à tous Je suis juste en train d'essayer de me concentrer sur l'utilisation de Refs pour cibler les éléments de mes composants pendant les transitions de routeur. actuellement Les événements onEnter, onExit et addEndListener de React Transition Group vous donnent déjà accès au nœud DOM que vous animez. Ce qui était bien pendant un certain temps, mais maintenant, comme vous le savez peut-être déjà, vous obtenez l'erreur.

index.js: 1 Attention: findDOMNode est obsolète dans StrictMode. findDOMNode a reçu une instance de Transition qui se trouve à l'intérieur de StrictMode. Au lieu de cela, ajoutez une référence directement à l'élément que vous souhaitez référencer. En savoir plus sur l'utilisation des références en toute sécurité [1]

voici mon code pour App.js

    import React from 'react';
    import { BrowserRouter as Router, Route } from 'react-router-dom';
    import { CSSTransition } from 'react-transition-group';
    import { gsap } from 'gsap';
  

    import Header from './tools/header';
    import About from './pages/about';
    import Home from './pages/home';

    const routes = [
        { path: '/', name: 'Home', Component: Home },
        { path: '/about', name: 'About', Component: About },

    ]

    function Routeapp() {

        const nodeRef = React.useRef(null);

        const onEnter = (node) => {
            console.log(node)

            gsap.from(
                [node.children[0].firstElementChild, node.children[0].lastElementChild],
                {
                    duration: 0.6,
                    y: 30,
                    delay: 0.6,
                    ease: 'power3.inOut',
                    opacity: 0,
                    stagger: {
                        amount: 0.3,
                    },
                }
            );

        };

        const onExit = node => {
            gsap.to(
                [node.children[0].firstElementChild, node.children[0].lastElementChild],
                {
                    duration: 0.6,
                    y: -30,
                    ease: 'power3.inOut',
                    opacity: 0,
                    stagger: {
                        amount: 0.15,
                    },
                }
            );
        };

      return (
        <Router>
          <Header />
          <div className="container">
              {routes.map(({ path, Component }) => (
                  <Route key={path} exact path={path}>
                      {({ match }) => (
                          <CSSTransition
                              in={match != null}
                              key={path}
                              timeout={1200}
                              classNames="page"
                              onEnter={onEnter}
                              onExit={onExit}
                              unmountOnExit={true}

                          >
                              <div className="page" ref={nodeRef} >
                                  <Component />
                              </div>
                          </CSSTransition>
                      )}
                  </Route>
              ))}
          </div>
        </Router>
      );
    }
    export default Routeapp;

Home.js

import React from 'react';
import Title from '../tools/title';

const Home = () => {
  return (

          <div className="inner">
              <Title lineContent="this is the" lineContent2="Home page" />
              <div className={'infoBox'}>
                  <p className="info">hello mel and welcome</p>
              </div>
          </div>
  );
};

export default Home;

about.js

import React from 'react';
import Title from '../tools/title';

const About = () => {
  return (

        <div className="inner">
          <Title lineContent={'this is the'} lineContent2={'About page'} />
          <div className={'infoBox'}>
            <p className="info pink">
              Lorem Ipsum is simply dummy text of the printing and typesetting
              industry. Lorem Ipsum has been the industry's standard dummy text ever
              since the 1500s, when an unknown printer took a galley of type and
              scrambled it to make a type specimen book. It has survived not only
              five centuries, but also the leap into electronic typesetting,
              remaining essentially unchanged. It was popularised in the 1960s with
              the release of Letraset sheets containing Lorem Ipsum passages, and
              more recently with desktop publishing software like Aldus PageMaker
              including versions of Lorem Ipsum.
            </p>
          </div>
        </div>
  );
};

export default About;

Mon problème est que j'essaie de trouver un moyen de «Ref» mes composants «Home» et «About» afin que je puisse non seulement les animer, mais aussi ajouter des interpolations différentes aux accessoires «onExit» et «onEnter si possible.

J'ai essayé de `` Ref '' les composants directement en essayant ceci dans app.js:

return (
    <Router>
      <Header />
      <div className="container">
          {routes.map(({ path, Component }) => (
              <Route key={path} exact path={path}>
                  {({ match }) => (
                      <CSSTransition
                          in={match != null}
                          key={path}
                          nodeRef={nodeRef}
                          timeout={1200}
                          classNames="page"
                          onEnter={onEnter}
                          onExit={onExit}
                          unmountOnExit={true}

                      >
                          <div className="page" ref={nodeRef} >
                              <Component />
                          </div>
                      </CSSTransition>
                  )}
              </Route>
          ))}
      </div>
    </Router>
  );

comme prévu, cela provoque l'arrêt de mon application car 'nodeRef' renvoie false et lorsque la propriété nodeRef est utilisée, le nœud n'est pas passé aux fonctions de rappel (par exemple onEnter) car l'utilisateur a déjà un accès direct au nœud.

J'ai donc juste besoin d'une nouvelle façon de le faire maintenant pour référence future, toutes les idées ou idées seront les bienvenues.

Merci

Réponses

2 W9914420 Sep 04 2020 at 01:08

Je veux donc simplement crier à @Slbox qui m'a inspiré à creuser plus profondément et à relooker le problème.

Avertissement

Je ne suis pas un programmeur expert ou professionnel en javascript et je ne suggère en aucun cas que c'est la seule façon de le faire, ma présentation doit être prise de manière abstraite. Mes pensées n'expliquent que les prémisses théoriques sur lesquelles la solution est basée et sa mise en œuvre dépendra de votre propre architecture.

Recherche du nœud 'findDOMNode'

Ainsi, en mode React Strict 'FindDomNode est déprécié et une approche conviviale' Ref 'est désormais privilégiée lorsque vous souhaitez faire référence à un élément de votre page. Comme tant d'autres, je recevais ce message d'erreur embêtant qui apparaît et vous indique que «findDOMNode a été déprécié en mode strict».

Cas d'utilisation (pourquoi lorsque vous rencontrez des problèmes)

Dans React Router, j'avais créé une transition de page simple en utilisant la combinaison de 'CSSTransition from' react-transition-group et de la plate-forme d'animation basée sur Javascript 'GSAP'. le problème que j'avais était que j'avais utilisé une approche de nœud DOM pour référencer les éléments de la manière préférée dans react.

1. Restructurez le composant de l'application

// So the App now has the routes contained inside each component in order for it
// to work and add additional functions and flexibility.

import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';

import './route.scss';

import Header from './tools/header';
import About from './pages/about';
import Home from './pages/home';

function Routeapp() {


  return (
    <Router>
      <Header />
      <div className="container">
          <Home /> <!-- routes and funcs -->
          <About /> <!-- routes and funcs -->
      </div>
    </Router>
  );
}

export default Routeapp;

2. La maison / à propos des composants

import React, {useRef} from 'react';
import Title from './title';
import { CSSTransition } from 'react-transition-group';
import {  Route} from 'react-router-dom';
import {gsap} from "gsap";


const Home = () => {

    // These two Refs are needed to refer to elements that we will be animating
    const title = useRef(null)
    const info = useRef(null)

    // This Ref will be used to make reference to the page of each component. 
    // My understanding is that this Ref will be used to distinguish between each 
    // component that is using 'CSSTransition' component and also removes the 
    // 'findDOMNode' warning
    const nodeRef = useRef(null)

    // This function is called immediately after the 'enter' 
    // or 'appear' class is applied from CSSTransition component.

    const onEnter = () => {
        gsap.from(
            [title.current,info.current],
            {
                duration: 0.6,
                y: 30,
                delay: 0.6,
                ease: 'power3.inOut',
                opacity: 0,
                stagger: {
                    amount: 0.3,
                },
            }
        );
    };


    // This function is called immediately after the 'exit' 
    // class is applied from CSSTransition component.
    const onExit = () => {
        gsap.to(
            [title.current,info.current],
            {
                duration: 0.6,
                y: -30,

                ease: 'power3.inOut',
                opacity: 0,
                stagger: {
                    amount: 0.15,
                },
            }
        );

    };


  return (

    <Route
        exact path={'/'}
        children={({ match }) => (
            <CSSTransition
                in={match != null}
                // time should not really be longer than the time it takes the animation
                // to leave the scene.
                timeout={1200}
                classNames={'page'}
                nodeRef={nodeRef}
                onEnter={onEnter}
                onExit={onExit}
                unmountOnExit
            >
                <div className={'page'} ref={nodeRef}>
                    <div className="inner">
                        <Title forwardRef={title} lineContent="this is the" lineContent2="Home page" />
                        <div ref={info} className={'infoBox'}>
                            <p className="info">hello stackOverflow and welcome</p>
                        </div>
                    </div>
                </div>
            </CSSTransition>
        )}
    />

  );
};


export default Home;

EXEMPLE GSAP et React-Router

Conclusion

C'est ma méthode pour obtenir cet effet, mais s'il existe des moyens meilleurs ou alternatifs, veuillez ajouter à la discussion et partager.