例子" Impure"零件

时间:2014-12-15 21:37:38

标签: reactjs

component specifications上的React docs部分讨论了保持render方法“纯粹”并解释这意味着什么。

我遇到了一些React抛出错误的情况,因为我在render做了一些不正确的事情,但是想知道是否存在组件可能“不纯”而不是触发的情况错误。

是否有人可以提供一个组件示例,该组件执行以下一项或多项操作而不会在React中引发错误?

  • 修改render中的组件状态(或其他任何不应该的组件状态)
  • 在不应该
  • 的情况下读取或写入DOM
  • 每次调用/渲染时都不会返回相同的结果
  • (可能与之前相同):不为相同的道具和状态呈现相同的DOM

1 个答案:

答案 0 :(得分:7)

假装这些都在渲染中。

"修改渲染中的组件状态(或其他任何地方不应该' t)

this.state.foo = whatever;

"读取或写入DOM时,不应该"

if (this.isMounted()) { this.getDOMNode().textContent = whatever };
document.querySelector('title').textContent = whatever;
每次调用/渲染时,

"都不会返回相同的结果"

return <div>{Math.random()}</div>

&#34;(可能与之前相同):不为相同的道具和状态渲染相同的DOM&#34;

if (new Date().getHours()>=9 && new Date().getHours()<=12+5) {
    return <div>{this.props.fortune}</div>
}
else {
    return <div>I'm off the clock</div>
}

您在评论中特别提到了最后一个示例,因此处理时间的正确方法是在getInitialState中获取时间,然后在componentDidMount中设置超时,以便在时间更改将影响渲染时使用setState。这样您的UI就与世界保持同步。

一个天真的解决方案是将setInterval设置为几秒钟,这很好,直到你有时间优化它。这里真正的解决方案就像是

var now = Date.now(),
    closing = new Date(); closing.setHours(12+5, 0, 0, 0),
    opening = new Date(); opening.setHours(9, 0, 0, 0), delay; 

// past closing
if (now > closing || now < opening) {
    if (opening < now) {
        opening.setHours(9+24);
    }
    delay = opening - now;
}
// currently open
else {
    delay = closing - now;
}
setTimeout(delay, updateStateWithTime);

就像任何状态随时间的变化一样,mixins通常是抽象和重用的好方法。