繁体   English   中英

onChange of <select>子组件中的元素未在React中重新呈现父状态,警告:未安装的组件

[英]onChange of <select> element in child component not re-rendering the parent state in React, Warning: unmounted component

我将状态从子级提升到父级,并尝试使用HTTP请求中的数据呈现选择元素。 Inv子组件中的选择标记值将显示以前选择的值,但是出现此错误:

警告:无法在已卸载的组件上调用setState(或forceUpdate)。 这是空操作,但它表明应用程序中发生内存泄漏。 要解决此问题,请在componentWillUnmount方法中取消所有订阅和异步任务。

看起来错误来自Inv子组件,该子组件正在使用this.state.identInvsData传递给道具。 那是我唯一的错误。 else语句中未获得identInvsData的子组件不会获得该错误消息。 父组件不会重新渲染或“装载”子组件。
关于我在做什么错的任何想法吗?

编辑:子组件正在从HTTP端点填充数据,但是onChange不会更改setState的值,只有当我选择按钮Add Inv 它添加了另一个孩子,但也允许以前的孩子进行更改。

身份父组件

class Identity extends React.Component {  

      state = {
        invIds: [],
        inTypes: [],
        invSeqIds: [],
        numChildren: 0,
        addInvBtnPressed: false
      };

      handleAddInv = () => {
        this.setState({
          numChildren: this.state.numChildren + 1,
          addInvBtnPressed: true
        });
      };

      onChangeInv = (e, index, sId) => {
        const invIdsArry = this.state.invIds;
        const invSeqIdsArry = this.state.invSeqIds;
        const newId = [
          ...invIdsArry.slice(0, index),
          (invIdsArry[index] = e.target.value),
          ...invIdsArry.slice(index + 1)
        ];
        if (sId) {
          const newSeqId = [
            ...invSeqIdsArry.slice(0, index),
            (invSeqIdsArry[index] = sId),
            ...invSeqIdsArry.slice(index + 1)
          ];
          this.setState({ invIds: newId, invSeqIds: newSeqId });
        } else {
          this.setState({ invIds: newId });
        }
      };

      onChangeType = (e, index) => {
        const invTypesArry = this.state.invTypes;
        const newTypes = [
          ...invTypesArry.slice(0, index),
          (invTypesArry[index] = e.target.value),
          ...invTypesArry.slice(index + 1)
        ];
        this.setState({ invTypes: newTypes });
      };


      render() {
        const children = [];
        var i;
        if (this.state.identInvsData && !this.state.addInvBtnPressed) {
          for (i = 0; i < this.state.numChildren; i += 1) {
            children.push(
              <Inv
                key={i}
                invKey={i}
                onChangeInv={this.onChangeInv.bind(this)}
                onChangeType={this.onChangeType.bind(this)}
                invId={this.state.identInvsData[i].invId}
                invType={this.state.identInvsData[i].invTypeCd}
                seqId={this.state.identInvsData[i].seqId}
                invData={this.state.identInvsData[i]}
              />
            );
          }
        } else if (this.state.identInvsData && this.state.addInvBtnPressed) {
          for (i = 0; i < this.state.numChildren; i += 1) {
            children.push(
              <Inv
                key={i}
                invKey={i}
                onChangeInv={this.onChangeInv.bind(this)}
                onChangeType={this.onChangeType.bind(this)}
              />
            );
          }
        } else {
          for (i = 0; i < this.state.numChildren; i += 1) {
            children.push(
              <Inv
                key={i}
                invKey={i}
                onChangeInv={this.onChangeInv.bind(this)}
                onChangeType={this.onChangeType.bind(this)}
              />
            );
          }
        }
        return (
          <div>
            <button
              type="button"
              className="btn btn-info"
              onClick={this.handleAddInv}
            >
              Add Inv
            </button>
            <div>{children}</div>
          </div>
        )
    }
}
export default Identity;

Inv子组件

class Inv extends React.Component {

    state = {
      kddLookupData: "",
      invData: ""
    };

    componentDidMount = () => {
      kddlookups_getAll().then(resp => {
        this.setState({
          kddLookupData: resp.data.item
        });
      });
      invs_getAll().then(resp => {
        this.setState({
          invData: resp.data.items
        });
      });
    };

    handleInvestigatorChange = e => {
      this.props.onChangeInv(e, this.props.invKey, this.props.seqId);
    };

    handleInvestigatorTypeChange = e => {
      this.props.onChangeType(e, this.props.invKey);
    };

    render() {
      return (
        <div>
          <select
            value={this.props.invId}
            name={this.props.invKey}
            onChange={this.handleInvChange.bind(this)}
          >
            <option className="blank">Select inv name:</option>
            {this.state.invData &&
             this.state.invData.map(inv => {
                return (
                   <option key={inv.userId} value={inv.userId}>
                      {inv.invName}
                   </option>
                );
              })}
          </select>

          <select
            value={this.props.invType}
            name={this.props.invKey}
            onChange={this.handleInvTypeChange.bind(this)}
          >
            <option className="blank">Select inv type:</option>
            {this.state.kddData &&
             this.state.kddData.kdd_inv_type.map(inv => {
               return (
                  <option key={inv.inv_type_cd} value={inv.inv_type_cd}>
                     {inv.inv_type_name}
                  </option>
               );
             })}
          </select>
        </div>
    )
  }
}
export default Inv;

看起来您没有在子组件的render函数中返回任何内容。 尝试:

render() {
return (
   <div>
      <select
        value={this.props.invId}
        name={this.props.invKey}
        onChange={this.handleInvChange.bind(this)}
      >
        <option className="blank">Select inv name:</option>
        {this.state.invData &&
         this.state.invData.map(inv => {
            return (
               <option key={inv.userId} value={inv.userId}>
                  {inv.invName}
               </option>
            );
          })}
      </select>

      <select
        value={this.props.invType}
        name={this.props.invKey}
        onChange={this.handleInvTypeChange.bind(this)}
      >
        <option className="blank">Select inv type:</option>
        {this.state.kddData &&
         this.state.kddData.kdd_inv_type.map(inv => {
           return (
              <option key={inv.inv_type_cd} value={inv.inv_type_cd}>
                 {inv.inv_type_name}
              </option>
           );
         })}
      </select>
      </div>
   );
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM