You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native随机名言应用改色报错与下滑过渡动画实现问题

报错问题修复

错误原因

  1. React Native 无DOM环境,不能用Web端直接操作ref.current.style的方式修改组件样式,该写法在RN中本身不兼容
  2. 你初始设置quotes为空数组,首次useEffect触发时要么quoteRef.current未完成挂载为undefined,要么组件还未渲染,直接访问style属性自然触发报错
  3. 原代码中使用了Platform但未导入,也会触发潜在报错

修复方案

新增颜色状态绑定样式,放弃ref直接操作样式的写法,拉取名言时同步生成随机颜色即可。

下滑动画实现

使用RN自带的Animated动画库即可实现,每次名言更新时控制文本Y轴偏移从上方负值平滑过渡到0,同步搭配透明度变化效果更自然。


修改后完整代码

import { StatusBar } from 'expo-status-bar';
import React from 'react';
// 新增导入Animated、Platform
import { StyleSheet, Text, View, Button, SafeAreaView, ScrollView, Animated, Platform } from 'react-native';
import { useState, useEffect, useRef } from 'react';

export default function App() {
  // 初始quotes改为null,避免首次渲染空值报错
  const [quotes, setQuotes] = useState(null);
  // 新增颜色状态
  const [quoteColor, setQuoteColor] = useState('#fff');
  // 动画值ref,控制下滑偏移和透明度
  const slideAnim = useRef(new Animated.Value(0)).current;
  let colors = ["#ffff00", "#90ee90","#ffa500", "#ff68ff", "#a9a9e7"]

  const getQuotes = () => fetch('https://quotable.io/quotes?page=1')
        .then(response => response.json())
        .then(data => {
            let randomQuote = Math.floor(Math.random() * data.results.length);
            setQuotes(data.results[randomQuote]);
            // 拉取到新名言时同步生成随机颜色
            setQuoteColor(colors[Math.floor(Math.random() * colors.length)]);
          });

  useEffect(() => {
    getQuotes()
  }, [])

  // 监听quotes变化,触发下滑动画
  useEffect(() => {
    if (!quotes) return;
    // 先重置动画值到上方-30位置,透明度为0
    slideAnim.setValue(-30);
    // 开启动画,150ms过渡到原位,透明度变为1
    Animated.timing(slideAnim, {
      toValue: 0,
      duration: 150,
      useNativeDriver: true
    }).start();
  }, [quotes, slideAnim])

  return (
    <SafeAreaView style={styles.container}>
      <ScrollView contentContainerStyle={{alignItems: 'center', justifyContent: 'center', flex: 1}}>
        {/* 替换为Animated.Text,绑定动画样式和颜色 */}
        {quotes && <Animated.Text 
          style={{
            color: quoteColor,
            fontSize: 18,
            transform: [{ translateY: slideAnim }],
            opacity: slideAnim.interpolate({
              inputRange: [-30, 0],
              outputRange: [0, 1]
            })
          }}
        >{quotes.content}</Animated.Text>}
        <Button
          onPress={getQuotes}
          title="Refresh"
          color="#841584"
          accessibilityLabel="Refresh"
          style={{marginTop: 20}}
        />
        <StatusBar style="auto" />
      </ScrollView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'blue',
    paddingHorizontal: 10,
    paddingTop: Platform.OS === 'android' ? 35 : 0,
  },
});

内容的提问来源于stack exchange,提问作者Ayse8888

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 17:36:05