React Native componentDidUpdate 道具未连接到主组件?

React Native componentDidUpdate props not connecting to main component?

当尝试向我的登录组件添加漂亮的 Lottie 动画时,我卡住了,因为在主组件文件上引用时,似乎无法识别 componentDidUpdate 中的道具。

来自 'this.props.isActive'(Lottie 组件)的

'isActive' 和 ''(主要组件文件)的 'isActive' 应该连接并触发动画,但不知何故它们没有。

Lottie组件代码

import React from "react";
import styled from "styled-components";
import LottieView from "lottie-react-native";
import { Animated, Dimensions } from "react-native";

const ScreenHeight = Dimensions.get("window").height;

class Success extends React.Component {
  state = {
    top: new Animated.Value(0),
    opacity: new Animated.Value(0),
  };

  componentDidMount() {}

  componentDidUpdate() {
    if (this.props.isActive) {
      Animated.timing(this.state.top, { toValue: 0, duration: 0 }).start();
      Animated.timing(this.state.opacity, { toValue: 1 }).start();

      this.animation.play();
    }
  }
  render() {
    return (
      <AnimatedContainer
        style={{ top: this.state.top, opacity: this.state.opacity }}
      >
        <LottieView
          source={require("../assets/checked-done.json")}
          autoPlay={false}
          loop={false}
          ref={(animation) => {
            this.animation = animation;
          }}
        />
      </AnimatedContainer>
    );
  }
}

export default Success;

const Container = styled.View`
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.9);
  justify-content: center;
  align-items: center;
  position: absolute;
  top: 0;
  left: 0;
`;

我正在尝试将其连接到的主要登录组件:

import React from "react";
import styled from "styled-components";
import {
  TouchableOpacity,
  TouchableWithoutFeedback,
  Keyboard,
} from "react-native";
import Success from "./Success";

class ModalLogin extends React.Component {
  state = {
    email: "",
    password: "",
    isSuccessful: false,
  };

  handleLogin = () => {
    console.log(this.state.email, this.state.password);
  };

  tapBackground = () => {
    Keyboard.dismiss();
  };

  render() {
    return (
      <TouchableWithoutFeedback onPress={this.tapBackground}>
        <Container
          style={{ backgroundColor: "grey" }}
          ref={(n) => {
            if (n && viewRef === null) {
              setViewRef(findNodeHandle(n));
            }
          }}
        >
          <Modal>
            <Logo source={require("../assets/logo.png")} />
            <Text>Manage your lessons</Text>
            <TextInput
              onChangeText={(email) => this.setState({ email })}
              placeholder="Email"
              keyboardType="email-address"
            />
            <TextInput
              onChangeText={(password) => this.setState({ password })}
              placeholder="Password"
              secureTextEntry={true}
            />
            <IconEmail source={require("../assets/icon-email.png")} />
            <IconPassword source={require("../assets/icon-password.png")} />
            <TouchableOpacity onPress={this.handleLogin}>
              <Button>
                <ButtonText>Login</ButtonText>
              </Button>
            </TouchableOpacity>
          </Modal>
          <Success isActive={true} />
        </Container>
      </TouchableWithoutFeedback>
    );
  }
}

export default ModalLogin;

const viewRef = styled.View``;

const Container = styled.View`
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.75);
  justify-content: center;
  align-items: center;
`;
const Modal = styled.View`
  width: 335px;
  height: 370px;
  background: white;
  border-radius: 20px;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
  align-items: center;
`;

const Logo = styled.Image`
  width: 90px;
  height: 90px;
  margin-top: 8px;
  margin-bottom: -8px;
`;
const Text = styled.Text`
  margin-top: 20px;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  width: 160px;
  text-align: center;
  color: #b8bece;
`;
const TextInput = styled.TextInput`
  border: 1px solid #dbdfea;
  width: 295px;
  height: 44px;
  border-radius: 10px;
  font-size: 17px;
  color: #3c4560;
  margin-top: 20px;
  padding-left: 44px;
`;
const Button = styled.View`
  background: #8dd2dc;
  width: 295px;
  height: 50px;
  justify-content: center;
  align-items: center;
  border-radius: 10px;
  margin-top: 20px;
`;

const ButtonText = styled.Text`
  color: white;
  font-weight: 600;
  text-transform: uppercase;
`;

const IconEmail = styled.Image`
  width: 30px;
  height: 30px;
  position: absolute;
  top: 174px;
  left: 31px;
`;

const IconPassword = styled.Image`
  width: 23px;
  height: 23px;
  position: absolute;
  top: 241px;
  left: 35px;
`;

还有Package.json

  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject"
  },
  "dependencies": {
    "@react-native-community/masked-view": "0.1.6",
    "@react-navigation/native": "^5.4.3",
    "expo": "~37.0.3",
    "lodash": "^4.17.15",
    "lottie-react-native": "^3.4.0",
    "native-base": "^2.13.12",
    "react": "~16.9.0",
    "react-dom": "~16.9.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz",
    "react-native-blur": "ndbroadbent/react-native-blur#android-fix",
    "react-native-calendars": "^1.265.0",
    "react-native-gesture-handler": "~1.6.0",
    "react-native-i18n": "^1.0.0",
    "react-native-material-design": "^0.3.7",
    "react-native-reanimated": "~1.7.0",
    "react-native-safe-area-context": "0.7.3",
    "react-native-screens": "~2.2.0",
    "react-native-web": "~0.11.7",
    "react-navigation": "^4.3.9",
    "react-navigation-stack": "^2.5.1",
    "react-navigation-tabs": "^2.8.13",
    "react-redux": "^7.2.0",
    "redux": "^4.0.5",
    "styled-components": "^5.1.0"
  },
  "devDependencies": {
    "@babel/core": "^7.8.6",
    "babel-preset-expo": "~8.1.0"
  },
  "private": true

componentDidUpdate() is invoked immediately after updating occurs. This method is not called for the initial render. https://reactjs.org/docs/react-component.html#componentdidupdate

componentDidUpdate 未在初始渲染时调用。因此,如果 isActive 属性开始时为真并且没有改变,那么它就不会触发你的动画。

<Success isActive={true} />

如果您希望动画在第一次渲染时播放,那么您还需要在 componentDidMount 中触发动画。

或者您可以重构以使用函数组件和挂钩。

useEffect(()=> {
  // animation code
}, [isActive])