【问题标题】:react is not updating components using state in class反应没有使用类中的状态更新组件
【发布时间】:2021-10-04 17:20:23
【问题描述】:

所以首先我尝试将空值分配给状态组件,然后再分配它们的值,所以这是我的类的构造函数

constructor(props){
        super(props);
        this.state = {
            Countrys:null,
            States:null,
            Citys:null
        }
    }

然后我为它们分配值是 ComponentDidUpdate 函数所以这是我的 componentDidMount 函数

componentDidMount() {
        navigator.geolocation.getCurrentPosition(function(position) {
          console.log(position)
          console.log("Latitude is :", position.coords.latitude);
          console.log("Longitude is :", position.coords.longitude);
        });
        this.setState({
          Countrys:Country.getAllCountries(),
            States:State.getAllStates(),
            Citys:City.getAllCities()
        })
        
        /*console.log("Country:: "+Country.getAllCountries()[0].name);
        console.log("City:: "+City.getAllCities()[0].name);*/

      }

然后我尝试在我的 jsx 元素中访问它们作为回报,使用这样的地图

 {this.state.Citys.map((ele ,index) =>
          <option value={`${ele}`} className="d-inline mx-2 col-sm-5" onClick={({target}) => target.classList.toggle('bg-primary')}>
          {ele.name}
         </option>
      )}

但它向我显示了错误

TypeError: Cannot read properties of null (reading 'map')

谁能告诉我这里出了什么问题或如何纠正它 当我尝试将类似 City.getAllCities() 的函数直接分配给 this.state 而不是将它们分配为 null 时,它显示页面无响应

而 City.getAllCities()、Country.getAllCountries()、State.getAllStates() 来自 npm 包“country-state-city”

【问题讨论】:

  • 您的构造函数将状态初始化为 null,因此在第一次渲染时,您会收到错误消息。在 ComponentDidMount 中设置会导致第二次渲染,它不会设置初始值。在尝试映射之前检查 null,或者将状态初始化为数组。
  • 另外,在 JS 约定中注意:变量使用 camelCase(首字母小写),类使用 CamelCase(首字母大写),因此您肯定希望将其更改为 state = { countries: null, states: null, cities: null }。虽然:为什么要在 componentDidMount 而不是构造函数中分配这些值?我没有看到您使用某种异步 I/O 进行获取,所以大概那些 CountryStateCity 对象已经存在:只需在构造函数的状态分配中使用它们?
  • @Mike'Pomax'Kamermans 再次检查最后几行问题 Country State and City are from npm package "country-state-city" 我的意思是它从那个包服务器获取数据跨度>
  • 什么“服务器”?节点模块是静态的(在这种情况下npmjs.com/package/country-state-city 清楚地表明这是您直接加载的静态数据)并且任何捆绑实用程序(esbuild、rollup、webpack 等)都会直接捆绑它们,所以我仍然看不到你为什么要在componentDidMount这样做?

标签: reactjs


【解决方案1】:

如果像您提到的那样,您使用的是country-state-city,那么完全没有理由将这三个值推迟到componentDidMount 加载:它们是来自country-state-city 包的静态导入。

只需将它们导入文件顶部,在构造函数中创建初始状态,分配这些值,然后在渲染过程中无需任何 null 状态即可完成。

import { Component } from "react";
import { Country, State, City }  from "country-state-city";
...

export class YourClass extends Component {
  constructor(props) {
    super(props);
    this.state = {
      countries: Country.getAllCountries(),
      states: State.getAllStates(),
      cities: City.getAllCities()
    };
  }

  render() { ... }
}

【讨论】:

    【解决方案2】:

    第一个渲染将 state.Citys 设置为 null,正如您在构造函数中设置的那样。

    ComponentDidMount 只会在第一次渲染后触发。

    你应该在构造函数中初始化状态

    【讨论】:

    • 我正在尝试这样做,但它显示我的页面在 chrome 中无响应,因为它需要花费时间来获取数据
    • 然后准备您的渲染函数来处理您的状态的空值,如果状态为空,则显示加载微调器或空白页面。
    • 例如:在return上面的那一行,可以加上if(!this.state.Citys) return null
    • @Bernado Ferreira Bastos Braga 你的意思是我可以使用具有上述条件的渲染来调用加载函数??
    • 我的意思是你可以有一个加载状态的条件渲染。在构造函数中,您的状态为空。您告诉我在 componentDidMount 中获取的状态需要一段时间才能获取。然后,您可以选择在状态加载时渲染其他内容。
    【解决方案3】:

    正如Bernardo Ferreira Bastos Braga 提到的,state.Citys 在第一次渲染中为空。
    您可以做的一件事是有条件地渲染。

     {this.state.Citys !== null && this.state.Citys.map((ele ,index) =>
              <option value={`${ele}`} className="d-inline mx-2 col-sm-5" onClick={({target}) => target.classList.toggle('bg-primary')}>
              {ele.name}
             </option>
          )}
    

    或者

     {this.state.Citys === null ? <SomeOtherComponent/Element/EmptyFragment/etc.. /> : this.state.Citys.map((ele ,index) =>
              <option value={`${ele}`} className="d-inline mx-2 col-sm-5" onClick={({target}) => target.classList.toggle('bg-primary')}>
              {ele.name}
             </option>
          )}
    

    在这些示例中,如果 state.Citys 为 null,则不会调用 map 函数。

    【讨论】:

      猜你喜欢
      • 2021-12-02
      • 1970-01-01
      • 2020-07-22
      • 2020-12-01
      • 2021-11-12
      • 1970-01-01
      • 1970-01-01
      • 2017-10-08
      相关资源
      最近更新 更多