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);
SpeechToText
从Speech 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
渲染<div>
。如果单击该按钮,则调用makeActive
方法并使状态处于活动状态——如果状态处于活动状态,我将呈现<SpeechToText>
。完成语音转文本后,我会调用 makeInactive
- 这会使状态处于非活动状态,<div>
会再次呈现
我第一次单击按钮时,SpeechToText
会被渲染并且语音到文本的工作。
但是,当我第二次单击该按钮时,我尝试重新渲染 SpeechToText
组件时出现错误:
setstate can only update a mounted or mounting component
有时错误不会出现,但语音转文本不起作用。
为什么会发生这种情况 - 我是否需要强制移除组件?
【问题讨论】:
'makeActive' 有什么作用? 您可以检查子组件中的active
吗?
默认状态为非活动状态。如果状态为非活动状态,我会使用按钮呈现 。如果单击该按钮,则调用makeActive
方法并使状态处于活动状态——如果状态处于活动状态,我将呈现 原来这是SpeechRecognitionContainer
的问题。
该软件包已使用新的道具和配置选项进行了更新,我解决了我的问题。
你可以阅读更多关于react-speech-recognition
here的信息。
现在我可以像这样渲染组件:
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(...) 只能更新已安装或正在安装的组件