Ilj*_*lja 11 javascript reactjs react-native
我刚刚更新,以反应原生0.54.0,其中还包括反应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)
);
}
}
Run Code Online (Sandbox Code Playgroud)
现在我有关于将此移植到的问题 static getDerivedStateFromProps
1)我不再有权访问this.props,因此无法访问以前的路径名,我想我可以将这些道具存储在状态中,这是正确的方法吗?似乎重复数据.
2)因为我无法访问this我无法调用我的动画功能,这依赖于一个状态.我怎么能绕过这个?
3)我需要首先设置状态,然后调用动画,因为getDerivedStateFromProps通过返回值设置状态,之后我做不了多少,所以有没有办法设置状态,之后执行回调?
4)pathnamebit仅用于componentWillreceiveProps现在,如果我将其移动到状态并且从不使用this.state内部getDerivedStateFromProps(因为我不能)this.state.pathname错误定义但从未使用过.这里最好的方法是使它静止吗?
我的第一直觉是改变它componentDidUpdate,但我们不应该setState在它内部使用正确吗?(这在我的场景中确实有效).
componentDidUpdate(prevProps: Props) {
if (this.props.pathname !== prevProps.pathname) {
this.setState({ previousChildren: prevProps.children, pointerEvents: false }, () =>
this.animate(0)
);
}
}
Run Code Online (Sandbox Code Playgroud)
注意:据我所知,我认为有一个功能出现在"悬疑"中,这将允许我们保持视图安装在组件卸载事件上?我无法找到任何参考,但这听起来像我可能用于这个动画的东西
对于任何感兴趣的人,这是一个有问题的完整组件的片段
// @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;
Run Code Online (Sandbox Code Playgroud)
hen*_*ngs 12
使用react版本16.3,使用componentWillReceiveProps正常,但会导致在控制台中显示弃用警告.它将在版本17中删除.FWIW Dan Abramov已警告不要在生产中使用alpha功能 - 但这是在2018年3月.
让我们来看看你的问题:
1)我不再能访问this.props,因此无法访问以前的路径名,我想我可以将这些道具存储在状态中.这是正确的方法吗?似乎重复数据.
是.
如果要更新/重新渲染组件,则应合并props和state.在您的情况下,您希望在pathname使用生命周期方法更改时更新组件/触发器动画.
似乎重复数据.
检查一下:React Team发布状态和生命周期
2)因为我无法访问这个,所以我无法调用依赖于状态的动画功能.我怎么能绕过这个?
componentDidUpdate
在每个重新渲染周期中完成渲染后,将调用此函数.这意味着您可以确保组件及其所有子组件已正确呈现.
这意味着你可以调用animate后setState在componentDidUpdate
3)我需要首先设置状态然后调用动画,因为getDerivedStateFromProps通过返回值设置状态,之后我做不了多少,所以有没有办法设置状态,之后执行回调?
请参阅第2点(使用componentDidUpdate)
4)pathname位目前仅在componentWillreceiveProps中使用,如果我将其移动到state并且从不在getDerivedStateFromProps中使用this.state(因为我不能)this.state.pathname错误被定义但从未使用过.这里最好的方法是使它静止吗?
不,它将由componentDidUpdate使用
这是我如何处理这个问题:
// @flow
import React, { Component, type Node } from "react";
type Props = {
pathname: string,
children: Node
};
type State = {
previousChildren: Node,
pointerEvents: boolean
};
class OnboardingRouteAnomation extends Component<Props, State> {
state = {
previousChildren: null,
pointerEvents: true,
pathname: ''
};
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.pathname !== prevState.pathname) {
return {
previousChildren: nextProps.children,
pointerEvents: false,
pathname: nextProps.pathname
};
}
return null;
}
componentDidUpdate(prevProps, prevState) {
if (prevState.pathname !== this.state.pathname){
console.log("prevState.pathname", prevState.pathname);
console.log("this.props.pathname", this.props.pathname);
this.animate(0);
}
}
componentDidMount(){
this.setState({ pathname: this.props.pathname});
}
animate = (value: 0 | 1) => {
console.log("this animate called", 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 (
<div>
{this.props.children}
</div>
);
}
}
export default OnboardingRouteAnomation;
Run Code Online (Sandbox Code Playgroud)
我相信这就是反应开发者应该如何处理的.您应该在更新后调用animate,componentDidUpdate因为它是副作用.
我将使用更具描述性的名称来指示路径已更改.有点像isPathUpdated.然后你可以animate检查isPathUpdated作为切换.
| 归档时间: |
|
| 查看次数: |
10094 次 |
| 最近记录: |