"不纯"组件的示例

can*_*era 5 reactjs

关于组件规范的React docs部分讨论了保持render方法"纯粹"并解释这意味着什么.

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

任何人都可以提供一个组件的示例,该组件执行以下一个或多个操作而不会在React中引发错误吗?

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

Bri*_*and 7

假装这些都是渲染.

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

this.state.foo = whatever;
Run Code Online (Sandbox Code Playgroud)

"当它不应该读取或写入DOM时"

if (this.isMounted()) { this.getDOMNode().textContent = whatever };
document.querySelector('title').textContent = whatever;
Run Code Online (Sandbox Code Playgroud)

"每次调用/渲染时都不会返回相同的结果"

return <div>{Math.random()}</div>
Run Code Online (Sandbox Code Playgroud)

"(可能与之前的相同):不会为相同的道具和状态呈现相同的DOM"

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>
}
Run Code Online (Sandbox Code Playgroud)

您在注释中特别提到了最后一个示例,因此处理时间的正确方法是在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);
Run Code Online (Sandbox Code Playgroud)

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