当前位置: 首页 > 面试题库 >

从渲染方法在React中调用setState()

连厉刚
2023-03-14
问题内容

我正在尝试使用setState()方法将容器中的React状态变量重置为默认值。但是出现以下错误

 Warning: setState(...): Cannot update during an existing state transithtml" target="_blank">ion 
(such as within `render` or another component's constructor). Render methods 
 should be a pure function of props and state; constructor side-effects are an anti-pattern, 
 but can be moved to `componentWillMount`.

最后:超出最大调用堆栈大小。

我的代码如下:

resetMsg=()=>  {  
const company = this.state.company;
company.id = 0;
company.messages = [];    
this.setState({company: company});       
}

当Redux状态的变量为true时,我正在调用resetMsg()。

我在其中调用resetMsg的代码(resetMessages的值最初为false,当它为true时,我需要重置React状态):

    render() {
    if(this.props.resetMessages){           
        this.resetMsg();           
    }

问题答案:

您可能要研究componentWillReceiveProps(nextProps)功能。根据官方文档:

componentWillReceiveProps()在已安装的组件接收新道具之前调用。如果您需要更新状态以响应道具更改(例如,将其重置),则可以比较this.props和nextProps并在此方法中使用this.setState()执行状态转换。

这是您要进行重置的地方。所以像这样:

componentWillReceiveProps(nextProps) {
  if(nextProps.resetMessages) {
    const company = Object.assign({}, this.state.company);
    company.id = 0;
    company.messages = [];    
    this.setState({company: company});
  }
}

每次将道具发送到组件时,以上代码段都会运行。它首先检查resetMessages道具是否真实。如果是,它将创建状态的临时副本company,更改idmessages属性值,然后company使用新的更新。

我想强调一下您的代码遇到的问题:

  1. 调用setState()里面render()是一个没有没有。

setState()一般情况下,只要您致电,此电话render()便会在以后运行。在render()自身内部执行此操作将导致该函数一次又一次地被调用…

  1. 直接改变状态和/或道具。

该行const company = this.state.company;不会创建状态变量的副本。它仅存储对其的 引用
。因此,一旦您执行了此操作,然后company.id = ...您实际上在执行this.state.company.id = ...,这就是React中的反模式。我们只会通过改变状态setState()

要创建副本,请将其Object.assign({}, this.state.yourObject)用于对象和this.state.yourArray.slice()数组。



 类似资料:
  • 我正在使用状态在图标的单击事件中打开和关闭一个层。当我从单击处理程序调用时,什么都没有发生。 以前,我直接从图标单击调用该方法,这确实打开了层,但如果由于不允许调用rednder()中的方法而冻结了用户界面。 所以我找到了一个解决方案,在调用打开之前添加一个lambda,如下所示。但是点击图标不会打开这个更改的图层: 为了进一步调试,我放置了一个控制台。登录方法,我可以看到它没有被点击图标。 问题

  • 问题内容: 我在尝试使用数据数组呈现元素时遇到问题。在的下面的代码中,可以正常工作,但列表项未出现。 我究竟做错了什么?请随时指出并非最佳做法的任何内容。 问题答案: GoshaArinich是正确的,您应该返回您的元素。但是,在这种情况下,您应该在浏览器控制台中收到讨厌的红色警告 数组或迭代器中的每个子代都应具有唯一的“键”道具。 因此,您需要在列表中添加“键”: 或使用es6 箭头功能放下并做

  • 问题内容: 我在弄清楚为什么我的应用程序执行无尽渲染时遇到问题。 在内部,我的有状态组件,我正在componentDidMount方法中调用redux动作(调用componentWillMount也可以进行无尽渲染) 在CoinCard中,我实际上不做任何事情(在Flat列表内注意CoinCard) 现在,当我控制台登录我的硬币卡渲染时,我可以 在此处* 看到 Inside rende的 无限日志

  • 问题内容: 我有一个组件,该组件获取作为道具的项目集合,并将其作为呈现为父组件子项的组件集合。我们使用以字节数组形式存储的图像。在函数中,我从项目中获取图像ID,并异步调用,以获取图像的字节数组。我的问题是我不能将诺言传播到React中,因为它不是设计来处理渲染中的诺言的(无论如何我还是不能说的)。我来自背景,所以我猜我在寻找类似关键字的内容来重新同步分支代码。 该函数看起来像这样(简化): 该方

  • 我正在react native项目中创建底部导航。对于以下编码,它工作正常。 但是我需要在标签上添加图标。所以我在屏幕上添加了以下道具 添加这些道具后,我得到以下错误 不变冲突:元素类型无效:需要字符串(对于内置组件)或类/函数(对于复合组件),但未定义。您可能忘记了从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入 根据文件,我做的每件事都是正确的。建议使用React导航文档中的道具

  • 我正在开发一个react native应用程序,它可以处理很多动画GIF。 我已经尝试使用react native documented library com。脸谱网。fresco:animated gif:1.3.0对于动画gif支持,默认图像组件的性能很差,但使用FastImage软件包,我最多可以获得10个gif。 由于有可能在React native中集成本机库,我想知道如何解决这个问题