2017-10-12 46 views
0

对不起,我不能拿出这个问题更具体的标题。当我执行下面的代码片段时,出现以下警告:正确地卸载反应组件

警告:setState(...):只能更新已安装或挂载的组件。这通常意味着您在卸载的组件上调用了setState()。这是一个没有操作。请检查打字机组件的代码。

但是,如果渲染()在MyComponent的被改变为如下,我没有得到任何这样的警告:

render() { 
    return (
    <div> 
     <h1> 
     <Typewriter /> 
     { this.state.render == 1 && "Render 1" } 
     { this.state.render == 2 && "Render 2" } 
     { this.state.render == 3 && "Render 3" } 
     </h1> 
    </div> 
); 
} 

如何正确卸载本身执行此渲染打字机组件的一些安装和卸载操作?谢谢!

class Typewriter extends React.Component { 
 
    constructor(props) { 
 
    super(); 
 
    this.state = { 
 
     finalText: '' 
 
    } 
 
    this.typeWriter = this.typeWriter.bind(this); 
 
    } 
 

 
    typeWriter(text, n) { 
 
    if (n < (text.length)) { 
 
     if (n + 1 == (text.length)) { 
 
     let j = text.substring(0, n+1); 
 
     this.setState({ finalText: j }); 
 
     n++; 
 
     } 
 
     else { 
 
     let k = text.substring(0, n+1) + '|'; 
 
     this.setState({ finalText: k }); 
 
     n++; 
 
     } 
 
     setTimeout(() => { this.typeWriter(text, n) }, 100); 
 
    } 
 
    } 
 

 
    componentDidMount() { 
 
    this.typeWriter('testing_typewriter', 0); 
 
    } 
 

 
    render() { 
 
    return (
 
     <div> 
 
     { this.state.finalText } 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
class MyComponent extends React.Component { 
 
    constructor(props) { 
 
    super(); 
 
    this.state = { 
 
     render: 1, 
 
     update: false 
 
    }; 
 
    this.interval = null; 
 
    } 
 

 
    componentDidMount() { 
 
    this.interval = setTimeout(() => 
 
     this.rendering(), 1700 
 
    ); 
 
    } 
 

 
    componentWillUpdate(nextProps, nextState) { 
 
    if (this.state.render < 3) { 
 
     this.interval = setTimeout(() => 
 
     this.rendering(), 1200 
 
    ); 
 
    } 
 
    } 
 

 
    componentWillUnmount() { 
 
     clearInterval(this.interval); 
 
     this.interval = null; 
 
    } 
 

 
    rendering() { 
 
    if (this.state.render < 3) { 
 
     if (this.interval) { 
 
     this.setState({ render: this.state.render + 1 }); 
 
     } 
 
    } 
 
    } 
 

 
    render() { 
 
    return (
 
     <div> 
 
     <h1> 
 
      { this.state.render == 1 && "Render 1" } 
 
      { this.state.render == 2 && <Typewriter /> } 
 
      { this.state.render == 3 && "Render 3" } 
 
     </h1> 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 

 

 
ReactDOM.render(<MyComponent />, app);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<div id="app"></div>

+0

我觉得你的问题是,你的父母组件试图取代打字机部件,后者已经完成了其打字机程序之前。我会建议采用“握手”方式而不是使用定时器。例如,您可以在父级中定义'typingDone'函数,然后将其作为道具传递给打字机组件,并在打字完成后稍后调用该方法。例如,'typingDone'函数可以通过更新状态来触发子组件的更改。 – Jaxx

+0

您正在使用'clearInterval'。你想要的是'clearTimeout'。 –

+0

另外,在打字机组件中,您并未设置对'setTimeout'的引用并将其清除到'componentWillUnmount'中。 –

回答

1

我也有类似的问题,我在您需要保持这种超时的轨道打字机功能清除超时/间隔在componentWillUnmount功能

解决它:

setTimeout(() => { this.typeWriter(text, n) }, 100); 

有点像

this._timer = setTimeout(() => { this.typeWriter(text, n) }, 100); 

然后添加一个生命周期方法:

componentWillUnmount() { 
    window.clearTimeout(this._timer); 
}