我在反应组件中有一个切换按钮:
toggleSpeak = () => {
this.setState({buttonOn: !this.state.buttonOn});
}
按钮会根据其状态改变其样式:
<img key="headphones" className={audioclass} src={this.state.buttonOn ? white : black} onClick={this.toggleSpeak}/>
这也会触发子组件中的一些内容:
play={this.state.buttonOn}
这会触发一些speechSynthesis回放,有时需要一段时间。问题是我希望用户意识到事情正在发生。但是,按钮不会立即改变其风格。只要我触发别的东西,无论是通过上面的孩子通过直通属性,还是通过触发redux动作,它仍然会延迟改变颜色几秒钟。
我希望立即改变颜色,因此用户知道不要继续重复它。我怎么能做到这一点?
答案 0 :(得分:1)
你在渲染中进行speechSynthesis吗? 在切换按钮后,您应该调用执行speechSynthesis的函数。 就UX而言,我建议您在执行可能需要一些时间才能完成的任务时显示加载指示器。此外,您可以禁用该按钮,直到speechSynthesis完成。
toggleSpeak = () => {
if(!this.state.doingSpeechSynthesis) {
this.setState(
{buttonOn: !this.state.buttonOn, doingSpeechSynthesis: true},
() => speechSynthesis(args, this.setState{doingSpeechSynthesis: false}));
}
}
答案 1 :(得分:1)
this.setState({})
函数确实是异步的,因此考虑到触发器中的所有内容都是
toggleSpeak = () => {
this.setState({buttonOn: !this.state.buttonOn});
}
你所说的明显延迟应该是不明显的。我认为延迟是从其他地方强加的。 (假设您需要在this.setState({})
之前运行其他同步代码。请向我们展示更多相关代码,以便我们更好地掌握正在发生的事情。
答案 2 :(得分:0)
我不确定这是否是“做出反应”的做法,但我想出了一个有效的解决方案。我将我传递的属性拆分为从按钮切换开启播放器。
state = {
buttonOn: false,
play: false
}
按钮属性与上面相同,随buttonOn状态而变化。
ChildComponent属性: ... play = {this.state.play}
然后,在按钮切换事件中,我等了半秒才改变播放状态。这样按钮会立即更新它的样式,然后所有玩家的东西都可以在打勾后运行。
togglePlay = (newValue) => {
this.setState({play: newValue});
}
toggleSpeak = (e) => {
let newValue = !this.state.buttonOn;
this.setState({buttonOn: newValue});
if (this.state.play != newValue) {
setTimeout(function() {
this.togglePlay(newValue);
}.bind(this), 500);
}
然后当然要清除卸载时的超时功能:
componentWillUnmount() {
clearTimeout(this.togglePlay);
}