#reactjs #animation #native #react-animated
#reactjs #Анимация #родной #реагирующий -анимированный
Вопрос:
У меня есть компонент, подобный компоненту, который принимает реквизит, и он отображается на основе этого реквизита. Каждый раз, когда этот реквизит изменяется, и компонент повторно отображается, я хочу, чтобы новый компонент появлялся примерно с 20dp, а старый компонент опускался как 20dp и исчезал. Я добился первого (простота ввода), но я не знаю, чего добиться во втором (простота вывода). Я думал, что мне нужно сделать это с помощью метода возврата useEffect (размонтировать), но анимация, похоже, не работает onMount.
function Component({status}: Props) {
if (status === 'x') return <AnimatedView status={status}><View> xxx <View /><AnimatedView />
<AnimatedView status={status}><View> yyy <View /><AnimatedView />
}
function AnimatedView ({status}: AnimatedProps) {
const animated = useRef(new Animated.Value(status === 'x' ? 1 : 0))
.current;
useEffect(() => {
const animation = Animated.timing(animated, {
toValue: status === 'x' ? 1 : 0,
duration: 200,
useNativeDriver: true
});
animation.start();
return () => {
animation.stop();
};
}, [animated, status]);
}
const styles = {
transform: [
{
translateY: animated.interpolate({
inputRange: [0, 1],
outputRange: status === 'x' ? [20, 0] : [0, 20]
})
}
],
opacity: animatedFormHeader.interpolate({
inputRange: [0, 1],
outputRange: status === 'x' ? [0, 1] : [1, 0]
})
};
Есть ли какой-либо способ добиться этого с помощью анимации ‘react-native’? Должен ли я использовать другой API? Могу ли я привести несколько примеров? На самом деле я думаю, что мне следует переписать все это, потому что я не думаю, что это хорошая идея, что анимация происходит на основе реквизита. Я просто хочу анимировать этот компонент при монтировании и при размонтировании.
Ответ №1:
Я создал компонент на основе того, что я понял из вышесказанного, надеюсь, это то, что вы хотели…
перекус: https://snack.expo.io/yjEX_u_Tu
export default ({ status }) => {
const [text, setText] = useState('');
const value = useRef(new Animated.Value(0)).current;
useEffect(() => {
const animation = Animated.timing(value, {
toValue: 1,
duration: 500,
});
animation.start(({ finished }) => {
if (finished) {
console.log(finished);
setText(status ? 'Hi' : 'Bye');
Animated.timing(value, {
toValue: 0,
duration: 500,
}).start();
}
});
}, [status]);
const translateY = value.interpolate({
inputRange: [0, 1],
outputRange: [0, 20],
});
const opacity = value.interpolate({
inputRange: [0, 1],
outputRange: [1, 0.2],
});
return (
<Animated.View
style={[styles.container, { opacity, transform: [{ translateY }] }]}>
<Animated.Text style={{ color: 'white' }}>{text}</Animated.Text>
</Animated.View>
);
};
Комментарии:
1. это действительно хороший подход, но проблема здесь в том, что у вас есть состояние, которое вы изменяете в useEffect, но в моем случае у меня есть «дочерние элементы», и анимация «облегчения» происходит при монтировании, а не при размонтировании.