如何在React Native中为setNativeProps使用useRef钩子? [英] How to use the useRef hook for setNativeProps in React Native?

查看:139
本文介绍了如何在React Native中为setNativeProps使用useRef钩子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将React Native的类组件转换为涉及 useRef 的功能组件.以下是类组件:

I'm trying to convert the class component of React Native to a functional component that involves 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:

someError.setNativeProps不是函数的TypeError.(在'someRef.setNativeProps({style:style})','someRef.setNativeProps'未定义)

TypeError that someRef.setNativeProps is not a function. (In 'someRef.setNativeProps({ style: style })', 'someRef.setNativeProps' is undefined)

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])

推荐答案

根据文档[1] ref的值保持为 ref.current .因此,您需要运行 someRef.current.setNativeProps .

As per the docs [1] The value of the ref is kept at ref.current. So you need to run someRef.current.setNativeProps.

这表示您的 useEffect 代码会出现问题,因为 useEffect 正在运行.您必须将 someRef.current 添加到 useEffect 依赖项数组,以便在 someRef 更新时调用该效果,并添加一个条件以不调用当 someRef.current null 时, someRef.current.setNativeProps .除非 someRef.current 不是 null ,否则您可能要跳过整个 useEffect 正文.

That said your useEffect code will have problems because someRef will be set to null on your first render when useEffect is running. 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. You may want to skip the entire useEffect body unless someRef.current is not 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

这篇关于如何在React Native中为setNativeProps使用useRef钩子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆