2016-06-09 5 views
1

반응 라우터에 문제가 있습니다.React 구성 요소의 상태에 따라 대응 라우터가 있음

const routes = (
<Route path="/" component={App}> 
    <IndexRoute component={HomePage}/> 
    <Route path="registration" component={Registration}> 
     <Route path="/registration-step-one" component={RegistrationStepOne} /> 
     <Route path="/registration-step-two" component={RegistrationStepTwo}/> 
     <Route path="/registration-step-three" component={RegistrationStepThree}/> 
     <Route path="/registration-step-four" component={RegistrationStepFour}/> 
    </Route> 
    <Route path="reset-password" component={PasswordReset} /> 
</Route> 
); 

나는 하나 개의 큰 요소 등록 네 단계를 가지고을 다음과 같이

내 경로 파일입니다. 제출 단추를 클릭하면 상태가 변경되고 다음 단계가 표시됩니다.

onButtonClick(name, event) { 
    event.preventDefault(); 
    switch (name) { 
     case "stepFourConfirmation": 
      this.setState({step: 1}); 
      break; 
     case "stepTwoNext": 
      this.setState({step: 3, errors: {}}); 
      break; 
     case "stepThreeFinish": 
      this.setState({step: 4}); 
      break; 
     default: 
      this.setState({step: 2, errors: {}}); 
    } 
} 

render() { 
    const languageReg = this.props.currentLanguage.default.registrationPage; 

    let formStep = ''; 
    let step = this.state.step; 
    switch (step) { 
     case 1: 
      formStep = (<RegistrationFormStepOne user={this.state.user} 
               onChange={this.setUser} 
               onButtonClick={this.onButtonClick} 
               onClick={this.changeStep} 
               errors={this.state.errors}/>); 
      break; 
     case 2: 
      formStep = (<RegistrationFormStepTwo user={this.state.user} 
               onChange={this.setUser} 
               onButtonClick={this.onButtonClick} 
               onClick={this.changeStep} 
               errors={this.state.errors}/>); 
      break; 
     case 3: 
      formStep = (<RegistrationFormStepThree user={this.state.user} 
                onFileChange={this.onFileChange} 
                onButtonClick={this.onButtonClick} 
                onClick={this.changeStep} 
                errors={this.state.errors} 
                files={this.state.files} 
                fileChosen={this.state.selectedFile}/>); 
      break; 

     default: 
      formStep = (<RegistrationFormStepFour user={this.state.user} 
                onChange={this.setUser} 

                onChangeCheckboxState={this.changeCheckboxState} 
                emailNotificationsState={this.state.user.emailNotifications} 
                termsState={this.state.user.terms} 
                smsNotificationsState={this.state.user.smsNotifications} 

                onButtonClick={this.onButtonClick} 
                onClick={this.changeStep} 
                errors={this.state.errors}/>); 
    } 

    return (
     <div className="sidebar-menu-container" id="sidebar-menu-container"> 

      <div className="sidebar-menu-push"> 

       <div className="sidebar-menu-overlay"></div> 

       <div className="sidebar-menu-inner"> 
        <div className="contact-form"> 
         <div className="container"> 
          <div className="row"> 
           <div className="col-md-10 col-md-offset-1 col-md-offset-right-1"> 
            {React.cloneElement(formStep, {currentLanguage: languageReg})} 
           </div> 
          </div> 
         </div> 
        </div> 
       </div> 
      </div> 
     </div> 
    ); 
} 

하지만이 예를 들어 세 번째 단계에있어 내가 브라우저에서 다시 클릭하면 나는 홈 페이지로 이동 해요 :

등록 구성 요소 코드입니다. 라우터를 반응시키는 방법은 홈페이지가 아닌 이전 단계에만 적용됩니까? 또는 상태를 사용하여 양식 단계를 변경하면 완료 할 수 없습니까?

답변

1

routerWillLeave 후크로이를 수행 할 수 있습니다. official react-router documentation에서 자세한 내용을 읽어보십시오.

여기에 당신이 할 수있는 작업은 다음과 같습니다

componentDidMount =() => { 
    this.props.router.setRouteLeaveHook(this.props.route, this.routerWillLeave); 
    //or this.context.router, depending on your app 
} 

routerWillLeave = (nextLocation) => { 
    if (this.state.step > 1) { 
    this.setState({step: this.state.step-1}); 
    return false; 
    } 
} 

위의 step 변화가 1보다 큰 경우 노선 변경을 방지 할 수 있습니다. 대신 setState이 호출되고 step이 1 감소하여 이전 단계의 렌더링이 강제 실행됩니다. step이 1이면 1 단계 이전에 이전 단계가 없으므로 실제로 역사에서 이전 페이지로 되돌아가는 것이 좋습니다.


당신은 또한 (손실되는 것을 방지하기 위해) 실제로 사용자가 양식에 일부 데이터가 채워진 경우 이전 페이지로 돌아 가기 전에 경로-휴가 확인 대화 요구에 관심이있을 수 있습니다. 이 경우 당신은 위의 코드에 추가 할 수 hasUnsavedData() 일부 사용자 지정 기능을 사용하면 그 모든 양식 요소를 확인하고 모든 입력 필드가 비어있는 경우에만 false을 반환 작성합니다

routerWillLeave(nextLocation) { 
    if (this.state.step > 1) { 
    ... 
    } else if (this.hasUnsavedData()) { 
    return "You have unsaved data. Are you sure you want to leave?" 
    } 

, 그렇지 않으면 true을.

+0

_TypeError : undefined_ – Boky

+0

의 'setRouteLeaveHook'속성을 읽을 수 없습니다. 대신'this.context.router .....'를 시도하십시오. 따라서'props'를'context'로 대체하십시오. – Chris

+0

컨텍스트를 사용할 수 있도록'RegistrationPage.contextTypes = { 라우터 : PropTypes.object } '을 추가했습니다. 하지만 이제는 _Uncaught TypeError : undefined_의 'step'속성을 읽을 수 없습니다. – Boky

관련 문제