react-router-native-stack icon indicating copy to clipboard operation
react-router-native-stack copied to clipboard

Warning: componentWillReceiveProps has been renamed and is not recommended for use.

Open JoeToeniskoetter opened this issue 4 years ago • 4 comments

componentWillReceiveProps method on the StackTransitioner component should be replaced with static getDerivedStateFromProps().

JoeToeniskoetter avatar Dec 20 '19 13:12 JoeToeniskoetter

getDerivedStateFromProps() or memoize() ?

Taymindis avatar Mar 12 '20 04:03 Taymindis

I have created with animation stack with getDerivedStateFromProps flow

react-router-native-animate-stack

Taymindis avatar Mar 24 '20 09:03 Taymindis

Seeing that this was opened last December and the issue still persist today I assume this project is dead?

Taymindis project unfortunately has its own flaws and also doesn't work

Dinkelborg avatar Sep 01 '20 19:09 Dinkelborg

So I took a look at where componentWillReceiveProps is actually used and checked what else react had in stock

I am fairly unexperienced in react so please correct me if the following is wrong but I replaced componentWillReceiveProps with shouldComponentUpdate in StackTransitioner.js and it seems to work fine

shouldComponentUpdate(nextProps,nextState) {
    const { history } = nextProps;
    const { location } = this.props;
    let _shouldUpdate = true;
    if(this.props === nextProps && this.state === nextState) _shouldUpdate = false;

    if (nextProps.location.key === location.key || !!this.state.transition) {
      return _shouldUpdate;
    }

    let action = history.action

    if (action === REPLACE && this.props.replaceTransitionType) {
        action = this.props.replaceTransitionType
    }

    const [children, previousChildren] = this.getChildren(nextProps.location, location);
    const routeAnimationType =
      action === PUSH ? (children && children.props.animationType) : (previousChildren &&  previousChildren.props.animationType)

    this.setState({
      previousLocation: location,
      routeAnimationType,
      children,
      previousChildren,
    });

    if (
      this.isPanning ||
      (routeAnimationType === NONE || (nextProps.animationType === NONE && !routeAnimationType)) ||
      (action === POP && history.index < this.startingIndex) ||
      (children && previousChildren && children.key === previousChildren.key)
    ) {
      return _shouldUpdate;
    }

    if (action === PUSH || action === POP) {
      this.setState(
        {
          transition: action,
        },
        () => {
          // TODO: base slide direction on `I18nManager.isRTL`
          const dimension = this.getDimension();

          this.props.isAnimating(true);

          this.animation = Animated.timing(this.animatedValue, {
            duration: getDuration(routeAnimationType || nextProps.animationType, action),
            toValue: action === PUSH ? -dimension : dimension,
            easing: getEasing(routeAnimationType || nextProps.animationType),
            useNativeDriver: true,
          }).start(({ finished }) => {
            if (finished) {
              this.props.isAnimating(false);

              this.setState({
                previousLocation: {},
                transition: null,
              });

              if (action === POP) {
                this.setState({
                  routeAnimationType: children.props.animationType,
                });
              }

              this.animatedValue = new Animated.Value(0);
              this.animation = null;
            }
          });
        }
      );
    }
    return _shouldUpdate;
  }

So maybe this could be adapted and thus fix the only issue I have with this plugin?

Dinkelborg avatar Sep 01 '20 19:09 Dinkelborg