我刚刚更新了react native 0.54.0,其中还包括react 16.3的alpha 1,当然我会收到很多关于componentWillMount
和componentWillReceiveProps
贬值的警告.
我有一个动画路由组件,它的核心依赖于componentWillReceiveProps
,它接收新路径,将其与前一个进行比较,如果它们是设置旧的子对象,则设置它们的动画,设置新的子对象并设置它们的动画.
下面是有问题的代码:
componentWillReceiveProps(nextProps: Props) {
if (nextProps.pathname !== this.props.pathname) {
this.setState({ previousChildren: this.props.children, pointerEvents: false }, () =>
this.animate(0)
);
}
}
现在我想问一下关于将其移植到static getDerivedStateFromProps
的问题
1) 我不再有访问this.props
的权限,因此无法访问以前的路径名,我想我可以将这些props 存储在状态中,现在这种方法正确吗?似乎是重复数据.
2) 由于我无法访问this
,我无法调用动画函数,这取决于状态.我怎么能绕过这个?
3) 我需要先设置状态,然后调用动画,因为通过返回值来设置getDerivedStateFromProps
个状态,之后我不能做很多事情,所以有没有办法设置状态,然后执行回调?
4) pathname
位现在只在componentWillreceiveProps
中使用,如果我将其移动到状态,并且在getDerivedStateFromProps
中从不使用this.state
(因为我不能)定义的this.state.pathname
个错误,但从未使用.这里最好的方法是让它也是静态的吗?
我的第一react 是把它改成componentDidUpdate
,但我们不应该在里面用setState
,对吗?(但在我的场景中,这确实有效).
componentDidUpdate(prevProps: Props) {
if (this.props.pathname !== prevProps.pathname) {
this.setState({ previousChildren: prevProps.children, pointerEvents: false }, () =>
this.animate(0)
);
}
}
NOTE:据我所知,我认为《悬念》中有一个功能,可以让我们在组件卸载事件中保持视图的安装?我找不到这方面的任何参考资料,但这听起来像是我可以在这部动画中使用的东西
对于任何感兴趣的人来说,这是一个完整组件的片段
// @flow
import React, { Component, type Node } from "react";
import { Animated } from "react-native";
type Props = {
pathname: string,
children: Node
};
type State = {
animation: Animated.Value,
previousChildren: Node,
pointerEvents: boolean
};
class OnboardingRouteAnomation extends Component<Props, State> {
state = {
animation: new Animated.Value(1),
previousChildren: null,
pointerEvents: true
};
componentWillReceiveProps(nextProps: Props) {
if (nextProps.pathname !== this.props.pathname) {
this.setState({ previousChildren: this.props.children, pointerEvents: false }, () =>
this.animate(0)
);
}
}
animate = (value: 0 | 1) => {
Animated.timing(this.state.animation, {
toValue: value,
duration: 150
}).start(() => this.animationLogic(value));
};
animationLogic = (value: 0 | 1) => {
if (value === 0) {
this.setState({ previousChildren: null, pointerEvents: true }, () => this.animate(1));
}
};
render() {
const { animation, previousChildren, pointerEvents } = this.state;
const { children } = this.props;
return (
<Animated.View
pointerEvents={pointerEvents ? "auto" : "none"}
style={{
alignItems: "center",
opacity: animation.interpolate({ inputRange: [0, 1], outputRange: [0, 1] }),
transform: [
{
scale: animation.interpolate({ inputRange: [0, 1], outputRange: [0.94, 1] })
}
]
}}
>
{previousChildren || children}
</Animated.View>
);
}
}
export default OnboardingRouteAnomation;