在React中使用setInterval延迟组件渲染

时间:2017-02-21 20:50:15

标签: javascript reactjs setinterval

我有一个父组件<App>

constructor() {
    super();            
    this.state = {
        transporterPos: 0
    }
    this.tick = this.tick.bind(this);
}

componentDidMount() {
    this.timerId = setInterval(() => this.tick(), 1000);
}

componentWillUnmount() {
    clearInterval(this.timerId);
}

tick() {
    let transporterPos = this.state.transporterPos;
    transporterPos++;
    if (transporterPos > 7) {
        transporterPos = 0;
    }
    this.setState({ transporterPos: transporterPos });
}

render() {
    return (
        <div>
            <Staves transporterPos={this.state.transporterPos}/>
        </div>
    );
}

<Staves>组件包含多个<Stave>组件,每个组件包含多个<Note>组件。每个<Note>组件都注入一个className条件,其active属性为true

<div className="noteContainer" onClick={this.handleClick}>
    <div className={"note" + (this.props.active ? ' active' : '')}></div>
</div>

handleClick()是一种切换<Note>的{​​{1}}属性的方法。我没有在这里包含所有代码以使其更具可读性。问题是,当点击active时,虽然其<Note>属性会立即更改,但“活动”的条件active给出的样式在之前不可见,直到该组件为在className方法的下一个“勾号”处重新渲染。换句话说,渲染似乎每1000ms就会发生一次。我希望它能立即发生。我使用setInterval错了吗?

修改

在回复评论时,这是setInterval方法(handleClick中):

<Note>

这会调用handleClick() { this.props.toggleActive(this.props.pos); } 中的toggleActive

<Stave>

toggleActive(pos) { this.props.notes[pos].active = !this.props.notes[pos].active; } 此处是props.notes的{​​{1}}的一部分,传递给<App>(我在此问题中未将其包含在内简洁)。

1 个答案:

答案 0 :(得分:1)

toggleActive(pos) {
    this.props.notes[pos].active = !this.props.notes[pos].active;
}

未触发重新渲染的原因是因为this.props直接变异而不是setState变异。将toggleActive进一步移动到您可以使用setState的位置。

如有必要,您可以将该功能作为道具传递给子组件,并通过this.props.toggleActive()

进行调用

除了不触发重新渲染之外,永远不应该直接变异this.props的另一个原因是因为只要父级更改状态并将props传递给子级,您的更改就会被覆盖。

相关问题