组件在console.log中渲染4次

时间:2019-11-28 10:38:29

标签: react-native expo react-lifecycle

首先,感谢您的阅读。我正在使用Expo开发本机。我使用componentWillMount和componentDidMount在我的应用中设置功能。 可以,但是我很难理解为什么我的组件渲染了4次...

我得到这个结果(通过console.log):

  

结果retrieveDeviceManufacturer():42   ===> retrieveProfileUserId 42结果retrieveDeviceUID():...结果retrieveDeviceOSVersion():10个结果   resolveDeviceManufacturer():Google连接类型wifi是   连接的?是

但是我每次执行组件都连续4次。 我当然是本机反应的新手,需要帮助才能完全理解这一点。

非常感谢您的帮助。这是我的整页代码:

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isFirstConnection: true };
    status: "0";
    deviceOSVersion: null;
    deviceManufacturer: null;
    deviceUID: null;
    profileUserId: null;
  }

  performTimeConsumingTask = async () => {
    return new Promise(resolve =>
      setTimeout(() => {
        resolve("result");
      }, 1000)
    );
  };
  componentWillMount = async () => {
    this.setState({ deviceOSVersion: await retrieveDeviceOSVersion() });
    this.setState({ deviceManufacturer: await retrieveDeviceManufacturer() });
    this.setState({ deviceUID: await retrieveDeviceUID() });
    this.setState({ profileUserId: await retrieveProfileUserId() });
  };

  async componentDidMount() {
    this.setState({ status: "6" });
    // Preload data from an external API
    // Preload data using AsyncStorage
    const data = await this.performTimeConsumingTask();

    if (data !== null) {
      this.setState({ isFirstConnection: false });
    }

    Font.loadAsync({
      Roboto: require("./assets/fonts/Roboto-Black.ttf")
    });
  }

  render() {
    if (this.state.status == "6") {
      console.log(
        "Results retrieveDeviceManufacturer() : ",
        this.state.profileUserId
      );
      if (this.state.profileUserId !== null && this.state.profileUserId > 0) {
        // OK
      } else {
        // Need connection
      }
      console.log("===>retrieveProfileUserId", this.state.profileUserId);

      // Device UUID
      console.log("Results retrieveDeviceUID() : ", this.state.deviceUID);
      if (this.state.deviceUID !== null) {
        // OK
      } else {
        // TODO : next step...
        storeDeviceUID(getDeviceUID());
      }

      // Detect Manufacturer : iOS, Android, ..
      if (this.state.deviceManufacturer !== null) {
        // OK
      } else {
        storeDeviceManufacturer(getDeviceManufacturer());
      }

      // Get system version
      if (this.state.deviceOSVersion !== null) {
        // OK
      } else {
        storeDeviceOSVersion(getDeviceOSVersion());
      }

      console.log(
        "Results retrieveDeviceOSVersion() : ",
        this.state.deviceOSVersion
      );
      console.log(
        "Results retrieveDeviceManufacturer() : ",
        this.state.deviceManufacturer
      );

      NetInfo.fetch().then(state => {
        console.log("Connection type", state.type);
        console.log("Is connected?", state.isConnected);
      });
      if (this.state.isFirstConnection) {
        return <SplashScreen />;
      }
      return <Navigation />;
    } else {
      console.log("STATUS INITIALISATION");
      this.setState({ status: "1" });
      return null;
    }
  }
}

3 个答案:

答案 0 :(得分:1)

查看您的console.log在渲染功能中打印4次的原因是因为您在componentWillMount内部添加了4个setState函数,

componentWillMount = async () => {
    this.setState({ deviceOSVersion: await retrieveDeviceOSVersion() });
    this.setState({ deviceManufacturer: await retrieveDeviceManufacturer() });
    this.setState({ deviceUID: await retrieveDeviceUID() });
    this.setState({ profileUserId: await retrieveProfileUserId() });
  };

因此,setState的每个实例将再次重新渲染应用程序,即再次调用render函数,因此这是一种不好的做法,因此render函数被调用了4次。尝试在SetState上编写所有内容,

componentWillMount = async () => {
        this.setState({ deviceOSVersion: await retrieveDeviceOSVersion(),deviceManufacturer: await retrieveDeviceManufacturer() ,
deviceUID: await retrieveDeviceUID(),profileUserId: await retrieveProfileUserId()});

      };

并尝试使用comopnentDidmount代替componentWillMount,因为它已被弃用。希望对您有帮助

答案 1 :(得分:0)

从我的代码中可以看到,在componentWillMount中,您呼叫setState 4次。一般来说,每当使用setState进行状态更改时,React都会重新渲染组件。您称呼它4次-您得到4次rerender(这是一种可能性)。

For additional info please refer here

在您开始注意到应用程序性能问题之前,我不会担心它,在这种情况下,我会考虑优化。但不是事先。

此外,componentWillMount已被弃用,您不应在组件中使用它。 Please refer here

希望这会有所帮助!

答案 2 :(得分:0)

每次调用setState时,React都会重新渲染所有组件和子组件吗?

默认答案是。