【问题标题】:Initialize Empty Class Array and populate from fetch Fetch function React初始化空类数组并从 fetch Fetch 函数 React 填充
【发布时间】:2021-07-09 03:51:27
【问题描述】:

我正在尝试使用 API 中的值填充下拉列表。我在反应类中声明了空数组,但无法为其分配值。我不能将它用作状态变量,因为我必须对以前开发的代码进行大量更改。我编写代码的方式options 没有定义。 下面发布了导致问题的部分代码。非常感谢任何帮助。

export default class LoadLimits extends Component {
   constructor(props){
    super(props);
    this.options = []
    this.getZoneOptions = this.getZoneOptions.bind(this)
   }
   render(){
       return (
          <PtSelect label="Assigned Zone" options={options} 
                  onChange={this.onChangeDropdown} 
                    disabled={this.props.disabled}
                     defaultVal={this.state.assignedZone} name="assignedZone" />                        
     )
   }
   getZoneOptions =  () =>{
        const zoneOptions = []
        const keys = []
        fetch(`${config.server}/getzoneOptions/`+this.props.ownModel.agencyId)
        .then(response=>
            {
                return response.json();
            })
            
        .then(data=>{
            for (var i =0;i<data[0].length;i++){
                if (data[0][i]['Zone_key']!==998){
                zoneOptions.push(data[0][i]['description'])
                keys.push(data[0][i]['Zone_key'])
                }
            }
           let dropOptions = zoneOptions.map((option,idx)=>{
            return {key:keys[idx],value: option, label:option}
           });   
           this.options = dropOptions
       })
        
        .catch(error=>{
            console.log(error);
        });
    
    }

}

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    问题

    传递给PtSelectoptions 未定义。

    <PtSelect
      label="Assigned Zone"
      options={options} // <-- should be this.options
      onChange={this.onChangeDropdown}
      disabled={this.props.disabled}
      defaultVal={this.state.assignedZone}
      name="assignedZone"
    />
    

    解决方案

    如果您需要一个变量来保存一个您不希望与 React 组件生命周期耦合的值,那么您可能应该使用 React ref

    1. 从“react”导入createRef
    2. options 创建一个可变引用。
    3. 实现componentDidMount生命周期方法来填充和设置options的当前值。
    4. 将当前的options 值传递给PtSelect 组件。

    代码

    import React, { Component, createRef } from 'react';
    
    class LoadLimits extends Component {
      constructor(props) {
        super(props);
        this.getZoneOptions = this.getZoneOptions.bind(this);
    
        this.options = createRef([]);
      }
    
      getZoneOptions = () => {
        const zoneOptions = [];
        const keys = [];
        fetch(`${config.server}/getzoneOptions/` + this.props.ownModel.agencyId)
          .then((response) => {
            return response.json();
          })
    
          .then((data) => {
            for (var i = 0; i < data[0].length; i++) {
              if (data[0][i]["Zone_key"] !== 998) {
                zoneOptions.push(data[0][i]["description"]);
                keys.push(data[0][i]["Zone_key"]);
              }
            }
            const dropOptions = zoneOptions.map((option, idx) => {
              return { key: keys[idx], value: option, label: option };
            });
            this.options.current = dropOptions;
          })
          .catch((error) => {
            console.log(error);
          });
      };
    
      componentDidMount() {
        this.getZoneOptions();
      }
    
      render() {
        return (
          <PtSelect
            label="Assigned Zone"
            options={this.options.current}
            onChange={this.onChangeDropdown}
            disabled={this.props.disabled}
            defaultVal={this.state.assignedZone}
            name="assignedZone"
          />
        );
      }
    }
    

    替代解决方案 - 使用 forceUpdate不强烈建议

    除了解决PtSelect 中的this.options 问题外,您还可以使用forceUpdate 告诉React 重新渲染,而不管任何状态和/或道具更新。这应该使用填充的选项重新呈现选择。

    component.forceUpdate(callback)
    

    默认情况下,当你的组件状态或道具改变时,你的 组件将重新渲染。如果您的 render() 方法取决于某些 其他数据,你可以告诉 React 组件需要重新渲染 致电forceUpdate()

    调用forceUpdate() 将导致render() 在 组件,跳过shouldComponentUpdate()。这将触发 子组件的正常生命周期方法,包括 shouldComponentUpdate() 每个孩子的方法。 React 仍然只会 如果标记发生变化,则更新 DOM。

    通常你应该尽量避免使用forceUpdate(),并且只 从render() 中的this.propsthis.state 读取。

    getZoneOptions = () => {
      const zoneOptions = [];
      const keys = [];
      fetch(`https://jsonplaceholder.typicode.com/users`)
        .then((response) => {
          return response.json();
        })
    
        .then((data) => {
          for (var i = 0; i < data.length; i++) {
            zoneOptions.push(data[i]["name"]);
            keys.push(data[i]["id"]);
          }
          let dropOptions = zoneOptions.map((option, idx) => {
            return { key: keys[idx], value: option, label: option };
          });
          this.options = dropOptions;
          console.log("Options ", this.options);
          this.forceUpdate(); // <-- trigger a rerender
        })
    
        .catch((error) => {
          console.log(error);
        });
    };
    

    【讨论】:

    • 只是好奇我们也可以处理{this.options ? &lt;PtSelect /&gt;:&lt;div/&gt;}{this options &amp;&amp; &lt;PtSelect/&gt;}
    • 我刚刚发现我错过了 PtSelect 中的 this 关键字。还有一个问题正在发生。页面加载后,下拉列表不会立即加载。我必须单击组件中的其他位置才能加载下拉列表。有什么帮助吗?我确实把函数放在了 componentDidMount 中。
    • @techipank 我假设 PtSelect 可以处理一个空数组,但是是的,如果使用 React ref,你可以有条件地在 this.options.current.length 上渲染。
    • @SouradipRoy 您也可以调用 this. getZoneOptions 作为回调(即 *some` onClick 处理程序)。
    • createRef([]) 也显示 TypeError。它说__webpack_require__.i(...) is not a function
    猜你喜欢
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 2021-12-24
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多