【问题标题】:React - Receiving "Uncaught TypeError: this.setState is not a function" in componentDidMount functionReact - 在 componentDidMount 函数中接收“Uncaught TypeError:this.setState is not a function”
【发布时间】:2021-06-03 21:10:01
【问题描述】:

我在我的 React 组件的 componentDidMount 函数中收到以下错误,我不确定原因:

未捕获的类型错误:this.setState 不是函数

我尝试绑定geocode 调用,但这似乎没有帮助。当我调用包含 setState 的本地函数时也会发生这种情况。

我已经在constructor 中绑定了componentDidMount 函数。

有人知道为什么会这样吗?

componentDidMount() {
        if (this.state.initialLoad) {
            navigator.geolocation.getCurrentPosition(
                (position) => {
                    const pos = {
                        lat: position.coords.latitude,
                        lng: position.coords.longitude,
                    };
                    let geocoder = new google.maps.Geocoder();

                    let latlng = pos;
                    geocoder.geocode({
                        'latLng': latlng
                    },
                        function (results, status) {
                            if (status === google.maps.GeocoderStatus.OK) {
                                console.log(results);
                                if (results[1]) {
                                    let addressObject = results[1].address_components;

                                    const cityType = 'locality';
                                    const stateType = 'administrative_area_level_1';

                                    let city = "";
                                    let state = "";

                                    for (let i = 0; i < addressObject.length; i++) {
                                        console.log(addressObject[i]);
                                        if (addressObject[i].types.includes(cityType)) {
                                            city = addressObject[i].long_name;
                                        } else if (addressObject[i].types.includes(stateType)) {
                                            state = addressObject[i].short_name;
                                        }

                                    }

                                    let isCityStateFound = city != "" && state != "";

                                    if (isCityStateFound) {
                                        jQuery('#city-search-ready-status').val('true');
                                    }

                                    let query = isCityStateFound ? city + ', ' + state : EmptyStr;

                                    console.log(query);

                                    jQuery('.tab-panel').find('.input-text input').val(query);

                                    this.setState({
                                        searchValueCity: city,
                                        searchValueState: state
                                    });

                                    this.performProviderSearch();
                                    this.performLocationSearch();
                                } else {
                                    console.log('No results found');
                                }
                            } else {
                                console.log('Geocoder failed due to: ' + status);
                            }
                        });
                });
        }
    }

【问题讨论】:

  • 绑定componentDidMount 不是必需的,因为在正确的上下文中调用它以使用引用组件实例的this。但是,您的所有回调函数还必须能够访问正确的 this 才能工作。 geocoder.geocode 的回调是您的问题,可以通过使用使用词法范围的箭头函数来纠正。
  • 谢谢。这行得通。这很有帮助。

标签: javascript reactjs


【解决方案1】:

欢迎来到 Stack Overflow 社区!!!

您可以使用 ES6 功能轻松解决所有问题。

  • 箭头函数 - 它们有一个词法作用域。所以你不必再绑定thisThis resource 很好地比较了 ES6 之前和之后的功能差异。
  • ES6 类 - 通过结合箭头函数的强大功能,您现在可以在类构造函数中创建无需绑定 this 的方法。
class App extends Component {
  state = {
    name: "",
  };

  componentDidMount() {
    if (this.state.initialLoad) {
      navigator.geolocation.getCurrentPosition((position) => {
        const pos = {
          lat: position.coords.latitude,
          lng: position.coords.longitude,
        };
        let geocoder = new google.maps.Geocoder();

        let latlng = pos;
        geocoder.geocode(
          {
            latLng: latlng,
          },
          (results, status) => {
            // Convert this also to an Arrow Function
            if (status === google.maps.GeocoderStatus.OK) {
              console.log(results);
              if (results[1]) {
                let addressObject = results[1].address_components;

                const cityType = "locality";
                const stateType = "administrative_area_level_1";

                let city = "";
                let state = "";

                for (let i = 0; i < addressObject.length; i++) {
                  console.log(addressObject[i]);
                  if (addressObject[i].types.includes(cityType)) {
                    city = addressObject[i].long_name;
                  } else if (addressObject[i].types.includes(stateType)) {
                    state = addressObject[i].short_name;
                  }
                }

                let isCityStateFound = city != "" && state != "";

                if (isCityStateFound) {
                  jQuery("#city-search-ready-status").val("true");
                }

                let query = isCityStateFound ? city + ", " + state : EmptyStr;

                console.log(query);

                jQuery(".tab-panel").find(".input-text input").val(query);

                this.setState({
                  searchValueCity: city,
                  searchValueState: state,
                });

                this.performProviderSearch();
                this.performLocationSearch();
              } else {
                console.log("No results found");
              }
            } else {
              console.log("Geocoder failed due to: " + status);
            }
          }
        );
      });
    }
  }

  performProviderSearch = () => {
    // Do whatever you want here
    this.setState({
      // Update the state
    });
  };

  performLocationSearch = () => {
    // Do whatever you want here
    this.setState({
      // Update the state
    });
  };

  render() {
    return (
      <div className="App">
        {/* Your HTML Structure */}
      </div>
    );
  }
}

注意 - 不要使用 jQuery 甚至使用 JavaScript 来操作 DOM。如果你这样做了,那么你就没有使用 React 的全部功能。

如果您需要进一步的支持,请告诉我。

【讨论】:

    【解决方案2】:

    尝试将geocoder.geocode的回调移动到组件中的单独函数,在构造函数中绑定它,并将其作为回调传递。 附言不需要绑定componentDidMount

    【讨论】:

    • 您已经确定了问题区域,但仅仅移动函数将无济于事,因为问题与范围有关(至少没有显式绑定新创建的函数)。
    猜你喜欢
    • 1970-01-01
    • 2014-12-30
    • 2018-12-31
    • 2017-03-11
    • 2023-02-17
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    • 1970-01-01
    相关资源
    最近更新 更多