是否总是在状态更新中调用componentDidMount()方法?

时间:2019-06-18 14:56:19

标签: android reactjs react-native

在componentDidMout()方法中,我开发了一个代码来查询Internet,但是如果此查询未成功完成(例如:超时),则用户可以选择更新状态并重新查询componentDidMount()。在更新中它仅调用render()方法,而没有其他问题。

/**
 * Textures List
 *
 * This file is responsible for requesting the server's texture information (api)
 * and printing on the screen.
 * @author David Gaspar
 */

// Importing modules
import React, { Component } from "react";
import { StyleSheet, FlatList, View, Text } from "react-native";
import { LoadingFailed, Loading } from "./Loading.js";
import { getData } from "../api/textures.js";

/**
 * Stateful Component
 *
 * @augments props
 */
export default class TexturesList extends Component {
  constructor(props) {
    super(props);

    this.state = {
      // Loading state
      isLoading: true,
      loadingFailed: false,
      loadingFailedMsg: null,
      // Textures list
      list: []
    };

    // Bind context to tha functions
    this.requestError = this.requestError.bind(this);
    this.requestSuccess = this.requestSuccess.bind(this);
    this.requestTryAgain = this.requestTryAgain.bind(this);
  }

  requestSuccess(data) {
    this.setState({
      isLoading: false,
      loadingFailed: false,
      list: data
    });
  }

  requestError(error) {
    this.setState({
      isLoading: false,
      loadingFailed: true,
      loadingFailedMsg: error.message
    });
  }

  requestTryAgain() {
    this.setState({
      isLoading: true,
      loadingFailed: false
    });
  }

  render() {
    const { requestTryAgain } = this;
    const { isLoading, loadingFailed, loadingFailedMsg, list } = this.state;
    const { container } = style;

    // Checking datas
    if (isLoading) {
      // It's loading
      return <Loading />;
    } else if (loadingFailed) {
      // Failed in loading
      return (
        <LoadingFailed msg={loadingFailedMsg} eventTryAgain={requestTryAgain} />
      );
    }

    // Success with HTTP communication
    return (
      <FlatList
        style={container}
        data={list}
        keyExtractor={this._keyExtractor}
        renderItem={this._renderItem}
      />
    );
  }

  componentDidMount() {
    const { requestSuccess, requestError } = this;
    const { isLoading } = this.state;

    if (isLoading) {
      getData("textures", requestSuccess, requestError);
    }
  }

  _keyExtractor(item, index) {
    return item.id;
  }

  // Rending item
  _renderItem({ item }) {
    // Getting item style
    const { itemStyle } = style;
    const { imagePath, name } = item;

    // Returning JSX
    return (
      <View style={itemStyle}>
        <Text>{name}</Text>
        <Text>{imagePath}</Text>
      </View>
    );
  }
}

const style = StyleSheet.create({
  container: {
    flex: 1
  },
  itemStyle: {
    width: "100%",
    height: 150
  }
});

3 个答案:

答案 0 :(得分:0)

componentDidMount在安装组件(插入树中)时被调用。

如果要触发组件更新,请使用componentDidUpdate()

https://reactjs.org/docs/react-component.html#componentdidupdate

答案 1 :(得分:0)

componentDidMount中的代码移动到函数,这将使您能够在requestTryAgain中再次调用该函数。

makeRequest = () => {
  const { requestSuccess, requestError } = this;
  const { isLoading } = this.state;

  if (isLoading) {
    getData("textures", requestSuccess, requestError);
  }
}

componentDidMount = () => {
  this.makeRequest();
}

在您的requestTryAgain中,将回调传递给setState,然后调用makeRequest

requestTryAgain = () => {

  this.setState({
    isLoading: true,
    loadingFailed: false
  }, () => {
     this.makeRequest();
  });
}

答案 2 :(得分:0)

ComponentDidMount挂钩在给定组件的整个生命周期中仅被调用一次,它确认您的组件已完全呈现。

由于保证此挂钩仅被调用一次,因此您不应期望它在此生命周期挂钩中获得更新状态。

我建议您使用静态getDerivedStatefromProps(nextProps,nextState),但是在这里您只能返回状态,因此您在此处调用的所有内容都应该是静态的,并在状态下返回其值以进行组件重新渲染 或componentDidUpdate(prevProps,prevState,快照)。基于您要在该组件上操作的状态。

让我知道我是否未回答您的期望,并发表评论以消除任何混乱。