2016-07-07 2 views
0

이 항목이 Protected HOC입니다. 그 목적은 사용자가 인증 될 때만 WrappedComponent을 렌더링하는 것입니다. 그렇지 않으면 AuthenticateComponent을 렌더링해야합니다 (일반적으로 로그인 구성 요소). 구성 요소에 대한감기 걸기 상태가 계속 표시되면 redux 상태가 표시되지 않아야 함

import React from "react" 

const PROPTYPES = { 
    authenticated: React.PropTypes.bool.isRequired, 
} 
export default (WrappedComponent, AuthenticateComponent) => { 
    let Protected = (props) => (
    props.authenticated 
    ? <WrappedComponent {...props}/> 
    : <AuthenticateComponent {...props}/> 
) 
    Protected.propTypes = PROPTYPES 
    return Protected 
} 

소품은

const AccountContainer = ({ children }) => (
    <div>{children}</div> 
) 
const select = state => state.account 
export default connect(select, { refreshUser, logout })(Protected(AccountContainer, LoginContainer)) 

account 감속기는 다음과 같습니다 연결된 REDUX 컨테이너 구성 요소에서 오는 :

function authenticated(state = false, action) { 
    switch (action.type) { 
    case actions.START_SIGNUP_SUCCESS: 
    case actions.LOGIN_SUCCESS: 
     return true 
    case actions.LOGIN_ERROR: 
    case actions.START_SIGNUP_ERROR: 
    case actions.LOGOUT_SUCCESS: 
     return false 
    default: 
     return state 
    } 
} 

... 

export default combineReducers({ 
    authenticated, 
    access_token, 
    loggingIn, 
    user, 
    error, 
}) 

그것은 LOGOUT 작업이 설정 될 때 이제 어떻게 state.account.authenticated 속성은 false로 설정되어 있지만 여전히 WrappedComponent은 렌더링됩니다. account의 다양한 다른 속성에 액세스하며 구성 요소가 확인하고 기대하지 않는 모든 속성도 이미 삭제되었습니다. WrappedComponent은 렌더링 될 때 account 상태가 여전히 authenticated이며 유효한 것으로 가정합니다.

어떤 종류의 경쟁 상태가 될지 궁금한가요?

답변

1

코드를 보지 않고도 알 수 없지만 감속기가 상태를 변경하는 것처럼 보입니다. 감속기는 절대로 국가를 돌연변이 시켜서는 안됩니다. 대신 올바른 속성으로 새 상태를 만들어야합니다.

그 중점은 경쟁 조건 및 기타 이상 현상을 방지하는 것입니다.

React Redux는 현재보고있는 문제를 방지하기 위해 신중하게 설계되었습니다. Redux 규칙을 준수해야합니다. 주된 하나는 감속기 순수 함수가되어야한다는 것입니다.

감속기가 이전 상태를 수정하고 대신 반환하면 Redux는 사용자가 상태를 수정했는지 쉽게 알 수 없습니다. 실제로 변경 사항이 없다고 가정합니다. 이와 같이 아무것도 다시 렌더링되지 않습니다.

편집 :

귀하의 감속기 내가 account 감속기가 다른 곳에서 사용하는 방법, 나는 그것뿐만 아니라 훌륭한 가정 해 볼 수는 없지만, 잘 보인다.

제가 생각하기에 문제는 실제로 구성 요소가 렌더링되지 않지만 렌더 메서드가 여전히 LOGOUT에 호출된다는 것입니다. 무슨 일이 일어나고있는 지, React는 해당 하위 구성 요소가 그러한 렌더링을 요청하면 하위 구성 요소를 행복하게 렌더링합니다. 그리고 connect이 업데이트되도록 store 업데이트로 연결되기 때문에, 이것이 계속됩니다. 당신의 상태 변경, connectmapStateToProps를 호출하여 WrappedComponentprops를 다시 평가하게하고 그 소품 (때문에 더 이상 로그인되기, 그리고 이전보다이 데이터 따라서 다른 존재) 변경된 것을 발견 할 것이다

. 그런 다음 Connect는 React에게 WrappedComponent을 다시 렌더링하도록 지시합니다. 반응은 그렇게 할 것입니다. 그러면 render 메서드는 사용자가 로그인 할 때만 사용할 수있는 유효하지 않은 데이터이기 때문에 전달되는 데이터에 문제가있을 수 있습니다.

해결 방법은 단순히 더미로 렌더링을 종료하는 것입니다 <div/>.가상 DOM 요소 인이 div는 실제로 DOM에 포함시키지 않습니다. React는 요소를 캐싱하고 DOM 업데이트를 일괄 적으로 처리합니다. 따라서 React는 그것을 DOM에 병합하기 전에 WrappedComponent 전체를 삭제할 것이고, 불행히도 새로운 버전을 이미 렌더링 한 후에야 React는 WrappedComponent 전체를 제거 할 것입니다.

Redux는 실제로 여기 범인 인 Redux입니다. Redux는 Components 개념을 가지고 있지 않으므로 계정을 고려할 수 없으며 Connect는 생성 된 순서대로 저장소에 가입하고 그런 다음 저장소는 구독 한 순서대로 구성 요소에 알립니다.

마지막 순서는 렌더링 순서와 장착 순서에 따라 다르며 많은 구성 요소가이 순서를 결정하는 역할을합니다. 그것은 단순히 안정적이지 않으므로 계산에 포함되어서는 안됩니다. 당신이 연결된 구성 요소를 빌드 할 때

, 당신의 mapStateToProps 취할 어떤 유효한 상태를 작성하고 대상 구성 요소에 대한 것과 유효 소품을 컴파일해야합니다. 더미 값을 추가하거나 구성 요소 자체를 변경하여 유효성 검사를 통과 한 모든 항목을 유효하게 만들지 여부에 상관없이 모든 유효 상태가 유효한 소품으로 해석되도록하는 것이 중요합니다. 이러한 소품 구성 요소는 표시되지 않습니다. 이렇게하면 유효한 상태 (실제로 로그 아웃되는 유효한 상태 임)로 인한 유효하지 않은 소품으로 인한 오류를 방지 할 수 있습니다.

당연히 무의미한 상태를 다루지 않아도되는 것은 당연합니다.

+0

내 감속기 코드로 내 질문을 편집했습니다. 너 괜찮 니? – philk

관련 문제