2017-10-12 90 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); 
}