J'utilise ReactHooks. J'essaie d'accéder à ref
du composant User
dans la fonction useEffect
. Mais je reçois elRef.current
valeur comme null
, même si j'ai réussi elRef.current
comme deuxième argument de useEffect
. Mais je suis censé obtenir une référence à l'élément div
. Mais en dehors (corps de la fonction) de useEffect
, la valeur de ref
est disponible. Pourquoi donc ? Comment puis-je avoir elRef.current
valeur entre useEffect
?
code
import React, { Component, useState, useRef, useEffect } from "react";
const useFetch = url => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(
() => {
setIsLoading(true);
fetch(url)
.then(response => {
if (!response.ok) throw Error(response.statusText);
return response.json();
})
.then(json => {
setIsLoading(false);
setData(json.data);
})
.catch(error => {
setIsLoading(false);
setError(error);
});
},
[url]
);
return { data, isLoading, error };
};
const User = ({ id }) => {
const elRef = useRef(null);
const { data: user } = useFetch(`https://reqres.in/api/users/${id}`);
useEffect(() => {
console.log("ref", elRef.current);
}, [elRef.current]);
if (!user) return null;
return <div ref={elRef}>{user.first_name + " " + user.last_name}</div>;
};
class App extends Component {
state = {
userId: 1
};
handleNextClick = () => {
this.setState(prevState => ({
userId: prevState.userId + 1
}));
};
handlePrevNext = () => {
this.setState(prevState => ({
userId: prevState.userId - 1
}));
};
render() {
return (
<div>
<button
onClick={() => this.handlePrevClick()}
disabled={this.state.userId === 1}
>
Prevoius
</button>
<button onClick={() => this.handleNextClick()}>Next</button>
<User id={this.state.userId} />
</div>
);
}
}
export default App;
Merci !
L'hypothèse ici est que useEffect
doit détecter les modifications de ref.current
, Donc doit avoir ref
ou ref.current
Dans la liste des dépendances. Je pense que cela est dû au fait que es-lint
Est un peu trop pédant.
En fait, tout l'intérêt de useEffect
est qu'il garantit de ne pas fonctionner tant que le rendu n'est pas terminé et que le DOM n'est pas prêt. C'est ainsi qu'il gère les effets secondaires.
Ainsi, au moment où useEffect
est exécuté, nous pouvons être sûrs que elRef.current
Est défini.
Le problème avec votre code est que vous n'exécutez pas le moteur de rendu avec <div ref={elRef}...>
Tant que user
n'est pas rempli. Le noeud DOM auquel vous voulez que elRef
fasse référence n'existe donc pas encore. C'est pourquoi vous obtenez la journalisation null
- rien à voir avec les dépendances.
BTW: une alternative possible est de remplir le div à l'intérieur du crochet d'effet:
useEffect(
() => {
if(!user) return;
elRef.current.innerHTML = `${user.first_name} ${user.last_name}`;
}, [user]
);
De cette façon, la ligne if (!user) return null;
dans le composant User n'est pas nécessaire. Supprimez-le et elRef.current
Est garanti d'être rempli avec le nœud div dès le début.