【问题标题】:Component renders 4 times in console.log组件在 console.log 中渲染 4 次
【发布时间】:2019-11-28 10:38:29
【问题描述】:

首先,感谢您阅读我的内容。我正在使用 Expo 进行本机反应。我使用 componentWillMount 和 componentDidMount 在我的应用程序中设置功能。 它可以正常工作,但是我很难理解为什么我的组件会渲染 4 次...

我得到了这个结果(使用我的 console.log):

结果检索设备制造商():42 ===>retrieveProfileUserId 42 结果retrieveDeviceUID() : ... 结果retrieveDeviceOSVersion() : 10 结果 retrieveDeviceManufacturer() :谷歌连接类型 wifi 是 连接的?真的

但是每次我执行该组件时连续 4 次。 我当然是 react-native 的新手,需要帮助才能完全理解这一点。

如果您能提供帮助,非常感谢。这是我的完整代码页:

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;
    }
  }
}

【问题讨论】:

    标签: react-native expo react-lifecycle


    【解决方案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 的每个实例都会再次重新渲染应用程序,即再次调用渲染函数,因此这是一种不好的做法,因此渲染函数被调用了 4 次。尝试在 SetState 中写入所有内容,

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

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

    【讨论】:

      【解决方案2】:

      从你的代码中我可以看到,在componentWillMount 中,你调用了setState 4 次。一般来说,每当使用setState 的状态发生变化时,React 都会重新渲染组件。你调用它 4 次 - 你得到 4 次重新渲染(这是一种可能性)。

      For additional info please refer here

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

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

      希望这会有所帮助!

      【讨论】:

        【解决方案3】:

        React 是否会在每次调用 setState 时重新渲染所有组件和子组件?

        默认答案是肯定的。

        【讨论】:

          猜你喜欢
          • 2017-12-04
          • 2020-07-14
          • 2011-12-23
          • 2021-10-21
          • 1970-01-01
          • 2019-05-26
          • 2021-10-31
          • 1970-01-01
          • 2020-12-08
          相关资源
          最近更新 更多