2017-10-21 152 views
0

所以這是多還是少的代碼競爭條件

很抱歉的語法,我從我的手機鍵入它

export default class Main extends React.Component { 

    componentDidMount() { 
    axios.get('/user?ID=12345') 
    .then(function (response) { 
    if (response){ 
    document.addEventListener('load',() => {/* remove spinner using jquery */}); 
} else { /* redirect to somewhere else */} 
    }) 
    } 

    render() { 
    return (
     <SomeComponent /> 
    ); 
    } 
} 

我用的addEventListener有反應,因爲我做不到找到任何其他方式將加載微調器的刪除綁定到加載事件。

問題是,在這裏出現了一場競賽,對於網速較慢的站點或快速的CPU站點,負載事件可能會在請求解決很久之前啓動,導致加載微調器保持不變。

有沒有可能檢查加載事件是否已被啓動?

如果我能做到這一點,我將能夠在添加事件偵聽器後檢查它,並且如果它已經啓動,我將手動刪除微調器。

+0

爲什麼使用jQuery的反應,而你可以簡單地setState? (這會觸發可以顯示或不顯示微調器的渲染方法)。我建議你閱讀[思考反應](https://reactjs.org/docs/thinking-in-react.html) – 3Dos

+0

setState重新呈現組件,我想避免它。我認爲將加載微調器的顯示設置爲無比簡單得多。 –

+0

但這不是問題 –

回答

3

我不會在這個任務中使用jquery(,或者根本就沒有反應),因爲您可以以更「反應敏捷」的方式進行操作。
當狀態發生變化時,您可以將數據存儲在state中,並有條件地將組件顯示在render方法中。
順便說一句,你無法避免第一個render

小例子:

const Loader =() => <div>Loading...</div> 
 

 
const MyComponent = ({message}) => <div>{message}</div> 
 

 
class App extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    this.state = { 
 
     message: '' 
 
    }; 
 
    } 
 

 
    componentDidMount(){ 
 
    // mimic async operation 
 
    setTimeout(()=>{ 
 
     this.setState({message: 'Hi there!'}) 
 
    }, 1500); 
 
    } 
 

 
    render() { 
 
    const {message} = this.state; 
 
    return (
 
     <div> 
 
     {message ? <MyComponent message={message} /> : <Loader />} 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
ReactDOM.render(<App />, document.getElementById("root"));
<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> 
 
<div id="root"></div>

編輯
作爲隨訪到您的評論:

但你重新渲染只是改變整個組件預加載器e的顯示樣式 lement,對嗎?

並不完全正確,我認爲你應該多看一些關於Reconciliation and The Diffing Algorithm,看看this例如:

陣營DOM元素和它的孩子到前面一個, 比較,並只適用於DOM的更新必要的將DOM帶到 所需的狀態。

+0

非常感謝您的回答。我已經做了一些模擬器。問題是componentDidMount沒有與load事件同步,並且可以很久之前啓動。這會導致預加載器在加載完成之前很長時間(尤其是在網絡速度較快且CPU速度較慢時)消失。我需要以某種方式與加載事件 –

+0

同步我沒有遵循,你設置承諾的回調內的狀態。這意味着你的狀態一直是空的,直到回調被調用(這意味着在回調之後第一個渲染應該顯示'Loader')設置一個重新呈現被調用的狀態,而現在另一個組件被返回而不是加載器。這個流程的問題在哪裏? –

+0

但是,然後你重新渲染整個組件只是爲了改變preloader元素的顯示樣式,對吧? –