A continuación hay dos componentes React que hacen casi lo mismo. Uno es una función; el otro es una clase. Cada Componente tiene un Animated.Value con un oyente asíncrono que actualiza _foo al cambiar. Necesito poder acceder a _foo en el componente funcional como lo hago con this._foo en el componente clásico.
FunctionalBar no debe tener _foo en el ámbito global en caso de que haya más de una FunctionalBar .FunctionalBar no puede tener _foo en el alcance de la función porque _foo se reinicializa cada vez que se procesa FunctionalBar . _foo tampoco debería estar en el estado porque el componente no necesita renderizarse cuando cambia _foo .ClassBar no tiene este problema porque mantiene _foo inicializado en this durante toda la vida del Componente. ¿Cómo mantengo _foo inicializado a lo largo de la vida de FunctionalBar sin ponerlo en el alcance global?
import React from 'react'; import { Animated, View } from 'react-native'; var _foo = 0; function FunctionalBar(props) { const foo = new Animated.Value(0); _onChangeFoo({ value }) { _foo = value; } function showFoo() { let anim = Animated.timing(foo, { toValue: 1, duration: 1000, useNativeDriver: true }); anim.start(() => console.log(_foo)); } useEffect(() => { foo.addListener(_onChangeFoo); showFoo(); return () => foo.removeListener(_onChangeFoo); }); return <View />; } import React from 'react'; import { Animated, View } from 'react-native'; class ClassBar extends React.Component { constructor(props) { super(props); this.state = { foo: new Animated.Value(0) }; this._foo = 0; this._onChangeFoo = this._onChangeFoo.bind(this); } componentDidMount() { this.state.foo.addListener(this._onChangeFoo); this.showFoo(); } componentWillUnmount() { this.state.foo.removeListener(this._onChangeFoo); } showFoo() { let anim = Animated.timing(this.state.foo, { toValue: 1, duration: 1000, useNativeDriver: true }); anim.start(() => console.log(this._foo)); } _onChangeFoo({ value }) { this._foo = value; } render() { return <View />; } }El gancho useRef no es solo para referencias DOM, sino que puede almacenar cualquier valor mutable que desee.
Ejemplo
function FunctionalBar(props) { const [foo] = useState(new Animated.Value(0)); const _foo = useRef(0); function showFoo() { let anim = Animated.timing(foo, { toValue: 1, duration: 1000, useNativeDriver: true }); anim.start(() => console.log(_foo.current)); } useEffect(() => { function _onChangeFoo({ value }) { _foo.current = value; } foo.addListener(_onChangeFoo); showFoo(); return () => foo.removeListener(_onChangeFoo); }, []); return <View />; }Puede usar useRef hook (es la forma recomendada que se indica en los documentos ):
const a = useRef(5) // 5 is initial valuea.currenta.current = my_valueSolo para apoyar la respuesta de Tholle aquí está la documentación oficial.
Sin embargo,
useRef()es útil para más que el atributo ref. Es útil para mantener cualquier valor mutable similar a cómo usaría los campos de instancia en las clases.Esto funciona porque
useRef()crea un objeto JavaScript simple. La única diferencia entreuseRef()y crear un objeto{current: ...}es queuseRefle dará el mismo objeto ref en cada renderizado.Tenga en cuenta que
useRefno le notifica cuando cambia su contenido. La mutación de la propiedad .current no provoca una nueva representación. Si desea ejecutar algún código cuando React adjunta o desconecta una referencia a un nodo DOM, es posible que desee utilizar una referencia de devolución de llamada en su lugar.