Storing non-state variables in functional components

后端 未结 4 1098
梦谈多话
梦谈多话 2020-12-25 10:45

Below are two React Components that do almost the same thing. One is a function; the other is a class. Each Component has an Animated.Value with an asy

相关标签:
4条回答
  • 2020-12-25 11:16

    Just to support Tholle answer here is the official documentation

    Reference

    However, useRef() is useful for more than the ref attribute. It’s handy for keeping any mutable value around similar to how you’d use instance fields in classes.

    This works because useRef() creates a plain JavaScript object. The only difference between useRef() and creating a {current: ...} object yourself is that useRef will give you the same ref object on every render.

    Keep in mind that useRef doesn’t notify you when its content changes. Mutating the .current property doesn’t cause a re-render. If you want to run some code when React attaches or detaches a ref to a DOM node, you may want to use a callback ref instead.

    0 讨论(0)
  • 2020-12-25 11:21

    You can use useRef hook (it's the recommended way stated in docs):

    • Declaring variable: const a = useRef(5) // 5 is initial value
    • getting the value: a.current
    • setting the value: a.current = my_value
    0 讨论(0)
  • 2020-12-25 11:23

    The useRef hook is not just for DOM refs, but can store any mutable value you like.

    Example

    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 />;
    }
    
    0 讨论(0)
  • 2020-12-25 11:38

    This is a pretty unusual example, but if I'm reading this correctly, you simply want to store unique _foo objects everytime the component mounts and destroy them when it unmounts, but also prevent extra rerenders when this value changes.

    I have run into this scenario before and simple object (map / hash) should do the trick:

    let foos = {}
    let fooCount = 0
    
    function F(props) {
      useEffect(() => {
        let fooId = fooCount++
        foos[fooId] = new Animated.Value(0)
        foos[fooId].addListener(...)
        return () => foos[fooId].removeListener(...)
      }, []) // <-- do not rerun when called again (only when unmounted)
    
      ...render...
    }
    

    or something to that effect. if you have a runnable example could tweak it to make it fit your example better. either way, most things with scope problems are solved with primitives.

    0 讨论(0)
提交回复
热议问题