当前位置: 首页 > 知识库问答 >
问题:

关闭模式对话框时尝试更新父属性的状态时出现反应错误

沈琛
2023-03-14

我有一个包含编辑选项的帐户表。单击编辑选项时,将显示帐户编辑模式对话框。用户可以通过单击右上角的“X”或单击关闭按钮来关闭或取消编辑。当模式关闭时,我想清除一些状态属性,包括对话框属性和父组件属性。对话框属性更新没有任何问题,但我收到这个错误时,父属性试图更新:

无法在现有状态转换期间更新(例如在渲染中)。渲染方法应该是道具和状态的纯函数。

这是父组件:

export class Accounts extends Component {

    constructor(props, context) {
        super(props);
        this.state = {
            loading: true,
            showEditUserModal: false,                
            userId: null,
            redraw: false,
        }
        this.handleAccountEdit = this.handleAccountEdit.bind(this);
    }

    handleAccountEdit(cell, row, rowIndex) {
        this.setState({ userId: cell },
            this.setState({ showEditUserModal: true }));
    }
    
    //This is parent function being called from dialog close Error occurs here
    handleAccountEditClose() {
        this.setState({ userId: null, showEditUserModal: false, redraw: true });
    }

    render() {
        return (
            <div className='container-fluid'>
                {this.state.showEditUserModal ?
                    <AccountEditModal userId={this.state.userId}
                        parentCloseAccountEditModal={() => this.handleAccountEditClose()}></AccountEditModal>
            </div>
            )
        }

AccountEditModal:

export default class AccountEditModal extends React.Component {
    constructor(props, context) {
        super(props);
        this.state = {
            uId: null,
            userName: '',
            showModal: true,
        }        
    }

    handleClose = (e) => {
        this.setState({ showModal: false, uId: null, userName: '' });
    }
    
    render() {        
        return (            
                <div >
                    <Modal show={this.state.showModal} onHide={() => { this.handleClose(); this.props.parentCloseAccountEditModal() }} centered >
                        <Modal.Header closeButton>
                            <Modal.Title>Account Edit</Modal.Title>
                        </Modal.Header>
                        <Modal.Body>
                            <div className="row">                                    
                                <div className="row pad-top float-right">
                                    <div className='col-md-2 my-auto'>
                                        <span id='btnCloseAccountEdit' onClick={() => { this.handleClose(); this.props.parentCloseAccountEditModal() }}
                                            className='btn btn-success'>Close</span>
                                    </div>
                                </div>
                            </div>
                        </Modal.Body>
                    </Modal>
                </div>
        )
    }

如何更新父组件属性而不出现此错误?

建议的解决方案不调用父组件函数。我在AccountEditModal中将handleClose更改为lambda,但仍然收到相同的错误。


共有2个答案

陆洛城
2023-03-14

重置组件的一个简单方法是使用密钥对其进行管理。见:https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-带钥匙的完全非受控组件

更准确地说:

当某个键发生更改时,React将创建一个新的组件实例,而不是更新当前组件实例。

因此,接下来,您可以使用一个时间码,这样每次调用这个模态窗口时,都会创建一个带有默认值的新实例。像这样:

<AccountEditModal 
    key={Date.now()} 
    userId={this.state.userId}
    parentCloseAccountEditModal={() => this.handleAccountEditClose()}> 
</AccountEditModal>

那么您就不需要这个函数和这个调用:this。handleClose() 只需调用这个:这个。道具。parentCloseAccountEditModal()下次调用该模式时,将有一个新实例。

对于普通组件,它可能会引入不需要的行为,但对于模式窗口,它通常正是目的:每次关闭/打开它时,您都需要一个重置状态,并且除了打开它之外,您不会更改道具-因为它是模式窗口,因此会阻止与父窗口的交互。

彭星津
2023-03-14

我不知道你在做什么,不同于我,但根据你的代码和解释,我创建了这个演示应用程序,它是正常工作,没有任何错误。您可能希望将其与应用程序进行比较,并检查应用程序中的不同之处。

在这里找到工作代码和盒子。

账户js

import React, { Component } from "react";
import { AccountEditModal } from "./AccountEditModal";

export class Accounts extends Component {
  constructor(props, context) {
    super(props);
    this.state = {
      loading: true,
      showEditUserModal: false,
      userId: null,
      redraw: false
    };
    this.handleAccountEdit = this.handleAccountEdit.bind(this);
  }

  handleAccountEdit(cell) {
    this.setState({ userId: cell }, this.setState({ showEditUserModal: true }));
  }

  //This is parent function being called from dialog close Error occurs here
  handleAccountEditClose() {
    this.setState({ userId: null, showEditUserModal: false, redraw: true });
  }

  render() {
    return (
      <div className="container-fluid">
        {this.state.showEditUserModal ? (
          <AccountEditModal
            userId={this.state.userId}
            parentCloseAccountEditModal={() => this.handleAccountEditClose()}
          ></AccountEditModal>
        ) : (
          <table>
            {this.props.users.map((uId) => {
              return (
                <tr>
                  <td>
                    <button onClick={() => this.handleAccountEdit(uId)}>
                      {uId}
                    </button>
                  </td>
                </tr>
              );
            })}
          </table>
        )}
      </div>
    );
  }
}

AccountEditModal。js

import React, { Component } from "react";
import { Modal } from "react-bootstrap";

export class AccountEditModal extends Component {
  constructor(props, context) {
    super(props);
    this.state = {
      uId: null,
      userName: "",
      showModal: true
    };
  }

  handleClose = (e) => {
    this.setState({ showModal: false, uId: null, userName: "" });
  };

  render() {
    return (
      <div>
        <Modal
          show={this.state.showModal}
          onHide={() => {
            this.handleClose();
            this.props.parentCloseAccountEditModal();
          }}
          centered
        >
          <Modal.Header closeButton>
            <Modal.Title>Account Edit: {this.props.userId}</Modal.Title>
          </Modal.Header>
          <Modal.Body>
            <div className="row">
              <div className="row pad-top float-right">
                <div className="col-md-2 my-auto">
                  <span
                    id="btnCloseAccountEdit"
                    onClick={() => {
                      this.handleClose();
                      this.props.parentCloseAccountEditModal();
                    }}
                    className="btn btn-success"
                  >
                    Close
                  </span>
                </div>
              </div>
            </div>
          </Modal.Body>
        </Modal>
      </div>
    );
  }
}

我在应用程序中添加了虚拟应用程序数据。js:

import React, { useState } from "react";
import { Accounts } from "./Accounts";

import "./styles.css";

export default function App() {
  const [users] = useState([
    "User1",
    "User2",
    "User3",
    "User4",
    "User5",
    "User6",
    "User7",
    "User8",
    "User9",
    "User10"
  ]);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Accounts users={users}></Accounts>
    </div>
  );
}
 类似资料:
  • 问题内容: 我尝试通过bash脚本执行此命令,但出现以下错误: 错误stacktrace: {“错误”:“ IndexPrimaryShardNotAllocatedException [[my_index]主要未分配后api]”,“状态”:409} {“错误”:“ ElasticSearchIllegalArgumentException [无法更新非动态设置[[index.analysis.f

  • 问题内容: 我处于状态的对象数组: 我需要能够基于id属性搜索items数组,然后更新对象属性。 我可以使用id参数通过数组或在数组上获取对象。 我遇到的麻烦是更新数组,然后更新状态而不会发生突变。 此时,我有一个匹配的对象,可以使用对象传播来更新它的属性: 我的问题是我该如何更新状态,以使其覆盖初始查找操作返回的对象? 问题答案: 您的更新功能如下所示 你这样使用它 毛吧? 如果您继续以这种方式

  • 我在尝试更新我的Eclipse时出错! 以下是在“安装下载0”期间发生内部错误的错误日志 Java . lang . illegalargumentexception:比较法违反了它的通用契约!at Java . util . comparabletimsort . merge hi(comparabletimsort . Java:835)at Java . util . comparablet

  • 在我看来,传奇模式在很多方面都是聚合模式的倒置。首先将命令处理成域事件,然后在聚合的情况下将此域事件应用到状态中是很有用的,但我认为在saga的情况下,域事件是已经发生的事情的文档,应该在试图对状态做出反应之前应用到状态中。 现在我的问题是:对于模块,有没有一种方法可以将命令配置为首先,然后?或者这是一个严重的bug,需要在一般情况下进行修复?

  • 我有JFrame和一个按钮,可以在点击事件时打开一个JPopupMenu。这个JPOppMenu有一个带有按钮的JPanel。这个按钮应该用来处理JPOppMenu。只要JFrame没有最大化,它就会这样做。但是,当JFrame最大化时,它会关闭JFrame本身。 任何有助于解决这一问题的帮助或建议都将不胜感激。 (我正在使用netbeans来开发这个。) 下面是MyJpanel的代码。

  • 问题内容: 在这里,我尝试设置为’hello’,然后打印它,但是状态似乎为空。当我刚刚使用更新状态时怎么办?设置为全局变量。 问题答案: 从reactjs文档中: 不会立即变异,但会创建待处理的状态转换。调用此方法后进行访问可能会返回现有值。 https://facebook.github.io/react/docs/component- api.html 您可以做的是将状态更新后传递给回调函数: