findDOMNode è deprecato in StrictMode come usare invece refs
Ciao a tutti Sto solo cercando di capire come usare Refs per indirizzare gli elementi nei miei componenti durante le transizioni del router. attualmente Gli eventi onEnter, onExit e addEndListener di React Transition Group ti danno già accesso al nodo DOM che stai animando. Il che è andato bene per un po ', ma ora come forse già sai ricevi l'errore.
index.js: 1 Avviso: findDOMNode è deprecato in StrictMode. findDOMNode è stata passata un'istanza di Transition che si trova all'interno di StrictMode. Invece, aggiungi un riferimento direttamente all'elemento a cui vuoi fare riferimento. Ulteriori informazioni sull'utilizzo sicuro degli ref [1]
ecco il mio codice per 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;
Il mio problema è che sto cercando di trovare un modo per 'Ref' i miei componenti 'Home' e 'About' in modo da non solo poterli animare, ma anche aggiungere interpolazioni diverse agli oggetti di scena 'onExit' e 'onEnter, se possibile.
Ho provato a 'Ref' i componenti direttamente provando questo in 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>
);
come previsto, questo fa sì che la mia applicazione smetta di funzionare poiché 'nodeRef' restituisce false e quando viene utilizzata la proprietà nodeRef, il nodo non viene passato alle funzioni di callback (ad esempio onEnter) perché l'utente ha già accesso diretto al nodo.
Quindi ho solo bisogno di un nuovo modo di farlo ora per riferimento futuro, eventuali intuizioni o idee saranno i benvenuti.
Grazie
Risposte
Quindi voglio solo gridare a @Slbox che mi ha ispirato a scavare più a fondo e riesaminare il problema.
Disclaimer
Non sono un programmatore esperto o professionista in javascript e non suggerisco assolutamente che questo sia l'unico modo per farlo, la mia presentazione dovrebbe essere presa in modo astratto. I miei pensieri spiegano solo le premesse teoriche su cui si basa la soluzione e l'implementazione di ciò dipenderà dalla tua architettura.
Trovare il nodo "findDOMNode"
Quindi, in modalità React Strict, 'FindDomNode viene deprezzato e un approccio amichevole' Ref 'è ora preferito quando si desidera fare riferimento a un elemento sulla pagina. Come tanti altri, stavo ricevendo quel fastidioso messaggio di errore che si apre e ti dice che "findDOMNode è stato deprezzato in Strict Mode".
Caso d'uso (perché dove hai problemi)
In React Router avevo creato una semplice transizione di pagina utilizzando la combinazione di "CSSTransition from" react-transition-group e la piattaforma di animazione basata su Javascript "GSAP". il problema che stavo avendo era che avevo usato un approccio del nodo DOM per fare riferimento agli elementi al modo preferito di reagire.
1. Ristrutturare il componente dell'app
// 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 home / sui componenti
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;
ESEMPIO GSAP e React-Router
Conclusione
Questo è il mio metodo per ottenere questo effetto, ma se ci sono modi migliori o alternativi, aggiungilo alla discussione e condividi.