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

查看:12
本文介绍了如何在 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:

类型错误,someRef.setNativeProps 不是函数.(在'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 将设置为 null代码> 正在运行.您必须将 someRef.current 添加到 useEffect 依赖项数组,以便在 someRef 更新时调用效果并添加不调用的条件someRef.current.setNativePropssomeRef.currentnull 时.您可能想要跳过整个 useEffect 主体,除非 someRef.current 不是 null.

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天全站免登陆