2017-10-21 1 views
0
그래서이 구문에 대한 더 많거나 코드를 덜

경쟁 조건이

죄송하다

, 내가 함께하여 addEventListener를 사용

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 /> 
    ); 
    } 
} 

반응 내 휴대 전화에서 입력 한 때문에 할 수 없었다 로딩 스피너의 제거를로드 이벤트에 바인딩하는 다른 방법을 찾습니다.

문제가 있습니다. 속도가 느린 네트워크 스테이션이나 빠른 CPU의 경 우에는로드 이벤트가 남아있어 요청이 해결되기 훨씬 전에 실행될 수 있습니다. 이로 인해로드 스피너가 유지됩니다.

로드 이벤트가 이미 지연되었는지 확인하는 방법이 있습니까?

할 수 있으면 이벤트 수신기를 추가 한 후에 확인할 수 있으며 이미 시작된 경우 수동으로 제거합니다.

+0

간단히 setState 할 수있는 동안 반응이있는 jQuery를 사용하는 이유는 무엇입니까? (이것은 스피너를 표시 할 수있는 렌더 메소드를 트리거합니다). [Think in Inactact] (https://reactjs.org/docs/thinking-in-react.html) – 3Dos

+0

setState가 구성 요소를 다시 렌더링하므로이를 피하고 싶습니다. 로드 스피너 표시를 none으로 설정하는 것이 훨씬 간단하다고 생각합니다. –

+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의 스타일 조준, 맞지?

하지 난 당신이 Reconciliation and The Diffing Algorithm에 대한 자세한 읽고 this 예를 살펴한다고 생각 완전히 사실 : DOM에 필요한 업데이트

는 DOM은 요소와 이전, 에 아이를 비교하여 반응에만 적용 DOM을 원하는 상태로 만듭니다.

+0

답장을 보내 주셔서 감사합니다. 나는 이미 멍청이를했다. 문제는 componentDidMount가 load 이벤트와 동기화되지 않고 오래 전에 실행될 수 있다는 것입니다. 이로 인해 프리 로더는 로딩이 완료되기 훨씬 전에 디스 파서를 발생시킵니다 (특히 네트워크가 빠르며 CPU가 느린 경우). 어떻게 든로드 이벤트와 동기화해야합니다. –

+0

다음과 같지 않습니다. 약속 콜백 내에서 상태를 설정합니다.즉, 콜백이 호출 될 때까지 상태가 비어 있음을 의미합니다 (즉, 첫 번째 렌더링이'Loader'를 표시해야 함을 의미합니다). 콜백 설정 후 다시 렌더링이 호출되고 이제는 다른 구성 요소가 로더 대신 반환됩니다. 이 흐름에 어떤 문제가 있습니까? –

+0

하지만 preloader 요소의 표시 스타일을 변경하기 위해 전체 구성 요소를 다시 렌더링합니다. –

관련 문제