React setstate 只能更新挂载或挂载的组件——在重新渲染时

Posted

技术标签:

【中文标题】React setstate 只能更新挂载或挂载的组件——在重新渲染时【英文标题】:React setstate can only update a mounted or mounting component -- on rerender 【发布时间】:2017-12-26 21:14:38 【问题描述】:

我正在使用react-speech-recognition 包在我的应用中进行语音转文本。

app.js 的内部渲染:

            <ChatContainer
              micActive=this.state.micActive
              sendData=this.sendData
              makeInactive=this.makeInactive
            >
                <SpeechToText>
                    sendData=this.sendData
                    makeInactive=this.makeInactive
                    micActive=this.state.micActive
                </SpeechToText>

                  <div>
                      <button
                        id="micInactive"
                        type="button"
                        onClick=this.makeActive
                      />
                  </div>

            </ChatContainer>

正如你在上面看到的,我的ChatContainer 有两个Children

    SpeechToText

    div 包含一个按钮

SpeechToText.js:

class SpeechToText extends Component 

    componentWillReceiveProps(nextProps) 
        if (nextProps.finalTranscript && nextProps.micActive) 
            this.props.sendData(nextProps.finalTranscript);
            this.props.resetTranscript();
            this.props.makeInactive();
        
    

    render() 
        return (
            <div>
                <button
                  id="micActive"
                  type="button"
                />
            </div>
        );
    


export default SpeechRecognition(SpeechToText);

SpeechToTextSpeech Recognition接收语音识别props

ChatContainer.js

const ChatContainer = props => (

    <div>
        
             React.Children.map(props.children, (child, i) => 
                 if (i === 0 && child.props.active) 
                     return React.cloneElement(child, 
                         sendData: props.sendData,
                         makeInactive: props.makeInactive,
                         micActive: props.micActive,
                     );
                 

                 if (i === 1 && child.props.inactive) 
                     return child;
                 
                 return null;
             )
        
    </div>
);

export default connect()(ChatContainer);

最终ChatContainer 决定渲染哪个child。如果状态为非活动状态,则使用非活动按钮呈现 div

编辑

默认情况下处于非活动状态 -- this.state.micActive: false。如果状态为非活动状态,我将使用button 渲染&lt;div&gt;。如果单击该按钮,则调用makeActive 方法并使状态处于活动状态——如果状态处于活动状态,我将呈现&lt;SpeechToText&gt;。完成语音转文本后,我会调用 makeInactive - 这会使状态处于非活动状态,&lt;div&gt; 会再次呈现

我第一次单击按钮时,SpeechToText 会被渲染并且语音到文本的工作。

但是,当我第二次单击该按钮时,我尝试重新渲染 SpeechToText 组件时出现错误:

setstate can only update a mounted or mounting component

有时错误不会出现,但语音转文本不起作用。

为什么会发生这种情况 - 我是否需要强制移除组件?

【问题讨论】:

'makeActive' 有什么作用? 您可以检查子组件中的active 吗? 默认状态为非活动状态。如果状态为非活动状态,我会使用按钮呈现 。如果单击该按钮,则调用makeActive 方法并使状态处于活动状态——如果状态处于活动状态,我将呈现 。一旦我完成了语音到文本的调用,我调用 makeInactive - 这使得状态处于非活动状态并且 再次呈现 @Tr1et 我编辑了问题并在上面回答了您的问题。有什么想法吗? 【参考方案1】:

原来这是SpeechRecognitionContainer 的问题。 该软件包已使用新的道具和配置选项进行了更新,我解决了我的问题。

你可以阅读更多关于react-speech-recognitionhere的信息。

现在我可以像这样渲染组件:

render() 
    return (
        <SpeechToText
          sendSpeechToText=this.sendSpeechToText

        />
    );

SpeechToText 看起来像这样:

class SpeechToText extends Component 

    constructor(props) 
        super(props);

        this.reactivate = this.reactivate.bind(this);
    

    componentWillReceiveProps(nextProps) 
        if (nextProps.finalTranscript && nextProps.micActive) 
            this.props.sendSpeechToText(nextProps.finalTranscript);
            this.props.resetTranscript();
            this.props.stopListening();
        
    

    componentWillUnmount() 
        if (this.props.listening) 
            this.props.abortListening();
        
    

    reactivate() 
        if (!this.props.listening) 
           this.props.startListening();
    

    render() 
        return (
            <div>
                <button
                  id="micButton"
                  type="button"
                  onClick=this.reactivate
                />
            </div>
        );
    


const options = 
  autoStart: false


export default SpeechRecognition(options)(SpeechToText)

【讨论】:

以上是关于React setstate 只能更新挂载或挂载的组件——在重新渲染时的主要内容,如果未能解决你的问题,请参考以下文章

React 警告:setState(...) 只能更新已安装或正在安装的组件

React Native - 第二次挂载时出现 setState 警告

react 生命周期

react组件生命周期

react组件通信与生命周期

react组件通信与生命周期