【问题标题】:React setstate can only update a mounted or mounting component -- on rerenderReact setstate 只能更新挂载或挂载的组件——在重新渲染时
【发布时间】: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

  1. SpeechToText

  2. 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 我编辑了问题并在上面回答了您的问题。有什么想法吗?

标签: javascript reactjs components voice-recognition


【解决方案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)

【讨论】:

    猜你喜欢
    相关资源
    最近更新 更多
    热门标签