无法在反应组件中使用 setState

Posted

技术标签:

【中文标题】无法在反应组件中使用 setState【英文标题】:Unable to use setState in react component 【发布时间】:2018-11-26 15:27:09 【问题描述】:

我有以下代码在安装后不允许我设置状态。

这里是代码

    import React,  Component  from 'react';
import Messages from '../locale/en/Messages';
import '../styles/base.css';

class AlertService extends Component 
    state = 
        message: '',
        classType: 'alert-info',
        isMessageSet: false
    

    Messages = new Messages();

    componentDidMount = () => 
        console.log('This has mounted'); // This is working
    
    componentWillUnmount = () => 
        console.log('Is this getting unounted ?'); // This is working, the component is not getting unmounted
    
    setAlert = (key, type, isMessage, readMore) => 
        let message = isMessage ? key : this.Messages[key];
        let classType = 'alert-info';
        if (type === 0) 
            classType = 'alert-danger';
         else if (type === 1) 
            classType = 'alert-success';
        
        this.openMessage(message,classType);


    
    openMessage = (message,classType) =>
        this.setState(
            message: message,
            classType: classType,
            isMessageSet: true
        );
    
    closeMessage = () => 
        this.setState(
            message: '',
            classType: 'info',
            isMessageSet: false
        );
    
    render() 
        let classes = this.state.classType + ' ' + 'alertBox';
        return (this.state.isMessageSet ? 

                                        <div className=classes>
                                           <div className="col-md-11"> this.state.message </div>
                                           <div className="col-md-1 closeAlert" onClick=this.closeMessage> x </div>


                                        </div>

                                : null
        )
    

export default AlertService;

尝试从该组件外部调用函数 setAlert 时出现以下错误。 但是,如果我将 isMessageSet 属性设置为 true 然后单击 X 并调用 closeAlert 方法,它可以正常工作。

componentDidMount 表示组件正在被挂载,componentWillUnmount 永远不会被执行,我不确定这里有什么问题

错误信息 无法在尚未安装的组件上调用 setState。这是一个无操作,但它可能表明您的应用程序中存在错误。而是直接分配给this.state 或在AlertService 组件中定义具有所需状态的state = ; 类属性。

【问题讨论】:

“在这个组件之外”是什么意思? 当有消息要显示时,我从另一个组件调用这个组件的setAlert函数,通过实例化AlertService类。 哦,有这样的用例。好吧,别理我的问题。 你在哪里叫它组件之外??? 【参考方案1】:

setState 不应从组件外部调用。如果要从外部更改状态,请使用道具。

正如错误消息所说,该组件未安装。您可以通过在布局中添加&lt;AlertService /&gt; 来安装它。

【讨论】:

【参考方案2】:

正如您在其中一个 cmet 中提到的,您在实例化 AlertService 类后尝试调用 setAlert 函数,我建议您查看一下您是如何执行此操作的。正确的做法是:

this.AlertService = React.render(React.createElement(AlertService), mountnode) //挂载组件 this.AlertService.setAlert() // 现在可以调用函数了

根据你的用例,你可以像上面那样做。

react 的问题是子组件的方法不能被父组件调用。由于这些是孩子的隐私,因此应由其自行处理。作为一种技巧,虽然我们可以使用 refs 来调用子组件的方法,但这不是 refs 的推荐用例。这可能会导致您的应用程序出现错误。

按照@vijayst 的建议,实现目的的最佳方法是在警报中更改父组件的状态(无论何时收到消息)并将其作为道具传递给子组件。现在在 componentWillReceiveProps() 下更新孩子的状态。

【讨论】:

非常感谢 componentWillReceiveProps 为我完成了这项工作【参考方案3】:

如果我理解正确,您说过您尝试从另一个组件调用 setAlert,但它不起作用,但是当您调用 closeMessage 时,它按预期工作,但后来我注意到您在同一个组件中调用了 closeMessage这将按预期工作,如果您想在另一个组件中调用属于该组件的函数,那么您需要将该组件导入该组件,然后将该函数传递给它,这样您就可以在该组件中调用该函数。例如:

import AnotherComponent from '../AnotherComponenet'

<AnotherComponent setAlert=this.setAlert />

【讨论】:

以上是关于无法在反应组件中使用 setState的主要内容,如果未能解决你的问题,请参考以下文章

尝试在反应组件的返回中使用 setstate 更新状态并获得“最大更新深度超出错误”?

无法在反应组件中呈现 JSON 数据

setState 更改状态但不重新渲染

反应功能组件未从父组件更新 setState

在脚本文本内容中反应 setState

在回调函数中使用 setState 挂钩时反应过多的重新渲染