我做了一个钩子来执行David Schumann告诉我的操作。
useColorAnimation.js
import { useRef, DependencyList, useMemo, useEffect, useState } from "react";
import { Animated } from "react-native";
const useColorAnimation = (color) => {
const anim = useMemo(() => new Animated.Value(0), [color]);
const [finished, setFinished] = useState(true)
const currentColor = useRef(color);
const nextColor = useMemo(()=> color, [color]);
const animColor = anim.interpolate({
inputRange: [0, 1],
outputRange: [currentColor.current, nextColor],
});
useEffect(() => {
setFinished(false)
Animated.spring(anim, {
toValue: 1,
useNativeDriver: false,
}).start(() => {
currentColor.current = nextColor;
setFinished(true)
});
}, [color]);
return [animColor, finished];
};
export default useColorAnimation
使用钩子:
import React, { useState } from 'react';
import { StyleSheet, Animated, Button } from 'react-native';
import useColorAnimation from './useColorAnimation';
const colors = ['rgb(0, 0, 0)', 'rgb(255, 0, 0)', 'rgb(0, 0, 255)'];
const getNextColor = (currentColor) => {
const index = colors.indexOf(currentColor) + 1;
return index == colors.length ? colors[0] : colors[index];
};
export default function App() {
const [color, setColor] = useState(colors[0]);
const [backgroundColor, finished] = useColorAnimation(color);
const handleButton = () => setColor((current) => getNextColor(current));
return (
<Animated.View style={[styles.container, { backgroundColor }]}>
<Button title="Next" onPress={handleButton} disabled={!finished} />
</Animated.View>
);
}
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
flex: 1,
},
});
这里是一个例子 https://snack.expo.dev/@rafaelnsantos/rude-croissant