findDOMNode est obsolète dans StrictMode comment utiliser les refs à la place
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
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.