简体   繁体   English

如何在 React Native 中为 setNativeProps 使用 useRef 钩子?

[英]How to use the useRef hook for setNativeProps in React Native?

I'm trying to convert the class component of React Native to a functional component that involves useRef .我正在尝试将 React Native 的类组件转换为涉及useRef的功能组件。 Following is the class component:以下是类组件:

import React, { Component } from "react";
import { AppRegistry, StyleSheet, Text, View, Animated, TouchableWithoutFeedback } from "react-native";

import { interpolateNumber, interpolateRgb } from "d3-interpolate";

export default class animations extends Component {
  state = {
    animation: new Animated.Value(0)
  };

  componentWillMount() {
    const positionInterpolate = interpolateNumber(0, 200);
    const colorInterpolate = interpolateRgb("rgb(255,99,71)", "rgb(99,71,255)");;

    this.state.animation.addListener(({value}) => {
      const position = positionInterpolate(value);
      const color = colorInterpolate(value);

      const style = [
        styles.box,
        {
          backgroundColor: color,
          transform: [
            {translateY: position}
          ]
        }
      ];
      this._view.setNativeProps({ style });
    });
  }

  handlePress = () => {
    Animated.timing(this.state.animation, {
      toValue: 1,
      duration: 500,
    }).start();
  }

  render() {
    return (
      <View style={styles.container}>
        <TouchableWithoutFeedback onPress={this.handlePress}>
          <View style={styles.box} ref={view => this._view = view} />
        </TouchableWithoutFeedback>
      </View>
    );

  }
}

When I convert to the following functional component, I get the following error:当我转换为以下功能组件时,出现以下错误:

TypeError that someRef.setNativeProps is not a function.类型错误 someRef.setNativeProps 不是函数。 (In 'someRef.setNativeProps({ style: style })', 'someRef.setNativeProps' is undefined) (在 'someRef.setNativeProps({ style: style })' 中,'someRef.setNativeProps' 未定义)

import 
    React, 
    { 
        useState, 
        useEffect,
        useRef
    } from 'react'
import {
    View,
    Animated,
    TouchableWithoutFeedback,
    StyleSheet
} from 'react-native'
import {
    interpolateNumber,
    interpolateRgb, 
} from 'd3-interpolate'

export default d3number = () => {
    const [animation] = useState(new Animated.Value(1))
    const [position, setPosition] = useState()
    const someRef = useRef(null)
    const startAnimation = () => {
        Animated.timing(animation, {
            toValue: 2,
            duration: 1500,
        }).start()
    }

    const positionInterpolate = interpolateNumber(0, 300)
    useEffect(() => {
        animation.addListener(({value}) => {
            const pos = positionInterpolate(value)
            setPosition(pos)
        })
        const style = [
            styles.box, 
            {
                transform: [
                    {
                        translateY: position
                    }
                ]
            }
        ]
        someRef.setNativeProps({ style })
        // console.log(someRef.setNativeProps)
    }, [])

    return (
        <View style={styles.container}>
            <TouchableWithoutFeedback onPress={startAnimation}>
                <View 
                    style={styles.box}
                    ref={someRef}
                />
            </TouchableWithoutFeedback>
        </View>
    )
}

Update: this was resolved by including the style within the listener更新:这是通过在侦听器中包含样式来解决的

        if (!someRef.current) {
            return;
        }
        animation.addListener(({value}) => {
            const style = [
                styles.box, 
                {
                    transform: [
                        {
                            translateY: positionInterpolate(value)
                        }
                    ]
                }
            ]
            someRef.current.setNativeProps({ style })            
        })

        // console.log(someRef.setNativeProps)
    }, [someRef.current])

As per the docs [1] The value of the ref is kept at ref.current .根据文档 [1] ref 的值保持在ref.current So you need to run someRef.current.setNativeProps .所以你需要运行someRef.current.setNativeProps

That said your useEffect code will have problems because someRef will be set to null on your first render when useEffect is running.这就是说你useEffect代码会出现问题,因为someRef将被设置为null的,当你第一次渲染useEffect运行。 You'll have to add someRef.current to the useEffect dependencies array so the effect is called whenever someRef updates and add a condition to not call someRef.current.setNativeProps when someRef.current is null .您必须将someRef.current添加到useEffect依赖项数组,以便在someRef更新时someRef效果,并添加一个条件以在someRef.currentnull时不调用someRef.current.setNativeProps You may want to skip the entire useEffect body unless someRef.current is not null .您可能想要跳过整个useEffect主体,除非someRef.current不为null

    useEffect(() => {
        if (!someRef.current) {
          return;
        }
        animation.addListener(({value}) => {
            const pos = positionInterpolate(value)
            setPosition(pos)
        })
        const style = [
            styles.box, 
            {
                transform: [
                    {
                        translateY: position
                    }
                ]
            }
        ]
        someRef.current.setNativeProps({ style })
    }, [someRef.current]) # note the addition of `someRef.current` here so the effect runs again when the ref is set

[1] https://reactjs.org/docs/hooks-reference.html#useref [1] https://reactjs.org/docs/hooks-reference.html#useref

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM