2017-08-28 112 views
0

我正在創建一個React組件來管理用戶輸入。 該組件,UserInput.js,有下面的方法,反應 - 條件渲染失敗,嘗試第二次顯示組件

renderOrigin - 顯示Form組件,

renderCities - 顯示與diferent道具相同的形式分量,

renderAddCitiesQuestion - 呈現兩個按鈕(是或沒有)其通過處理,

handleContinue - 設置狀態下與答案「繼續」問題

getChildSate - 設置用t接收到的狀態他的子組件(如表格)

渲染 - 基於狀態的條件渲染。 State具有布爾屬性'start'(用於第一個渲染),'rendercities'和'renderQuestion'。

有條件的流程如下。 首先,state.start是真的,我們稱之爲renderOrigin; 比,state.start變成false,state.renderCities成爲true,我們調用renderCities();比state.rendercities變成false並且state.renderQuestion變爲true,這使得我們調用renderAddCityQuestion();現在有兩種可能:用戶點擊No按鈕,我們不應該渲染任何東西,或者他點擊Yes和state.renderCities成爲true(並且state.renderQuestion成爲false),它調用renderCities()(並且它被調用,i通過console.log查看它),但該組件不會呈現,而問題組件仍然可見。

我看不到發現錯誤。 以下是整個程式碼。

import React from 'react'; 
 
import Form_city from './Form_city'; 
 

 
class UserInput extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    this.getChildState = this.getChildState.bind(this); 
 
    this.handleContinue = this.handleContinue.bind(this); 
 
    this.renderOrigin = this.renderOrigin.bind(this); 
 
    this.renderCities = this.renderCities.bind(this); 
 
    this.renderAddCitiesQuestion = this.renderAddCitiesQuestion.bind(this); 
 
    this.state = { 
 
     origin: null, 
 
     cities: [], 
 
     renderCities: false, 
 
     renderQuestion: false, 
 
     start: true 
 
    } 
 
    } 
 

 
    getChildState(stateName, stateVal) { 
 
    console.log('setting state. received stateName, stateVal', stateName, stateVal); 
 
    this.setState({ 
 
     [stateName] : stateVal 
 
    }); 
 
    console.log('set state done: ', this.state); 
 
    } 
 

 
    handleContinue(answer) { 
 
    this.state.renderQuestion = false; 
 
    answer === 'yes' ? this.state.renderCities = true : this.state.renderCities = false; 
 
    console.log('state after clicking answer: ', this.state); 
 
    this.render(); 
 
    } 
 

 
    renderOrigin() { 
 
    return(
 
     <div> 
 
     <Form_city 
 
      divName="originForm" 
 
      text="Please select an Origin:" 
 
      type="origin" 
 
      placeHolder="Origin" 
 
      getChildState={this.getChildState} 
 
     /> 
 
     </div> 
 
    ); 
 
    } 
 

 
    renderCities() { 
 
    console.log('rendering city form'); 
 
    return(
 
     <div> 
 
     <Form_city 
 
      divName="citiesForm" 
 
      text="Which city do you want to visit?" 
 
      type="cities" 
 
      placeholder="Destination" 
 
      getChildState={this.getChildState} 
 
     /> 
 
     </div> 
 
    ); 
 
    } 
 

 
    renderAddCitiesQuestion() { 
 
    console.log('rendering question'); 
 
    return(
 
     <div> 
 
     <p>Do you want to visit any other city?</p> <br /> 
 
     <button type="button" onClick={this.handleContinue.bind(this, 'yes')}>Yes</button> 
 
     <button type="button" onClick={this.handleContinue.bind(this, 'no')}>No</button> 
 
     </div> 
 
    ); 
 
    } 
 

 
    render() { 
 
    console.log('inside render\n, state: ', this.state); 
 
    let content = null; 
 
    if (this.state.start === true) { 
 
     console.log('inside render origin conditional'); 
 
     content = this.renderOrigin(); 
 
    } else if (this.state.renderCities === true) { 
 
     console.log('inside render cities conditional'); 
 
     content = this.renderCities(); 
 
    } else if (this.state.renderQuestion === true) { 
 
     console.log('inside render question conditional'); 
 
     content = this.renderAddCitiesQuestion(); 
 
    } else { 
 
     content = <p>Weird stuff?</p> 
 
    } 
 

 
    return(
 
     <div> {content} </div> 
 
    ); 
 
    } 
 

 
} 
 

 
export default UserInput;

這裏也是完整性緣故表單組件。

import React from 'react'; 
 

 
class Form_city extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    this.state = {data: ''}; 
 
    this.handleSubmit = this.handleSubmit.bind(this); 
 
    this.handleChange = this.handleChange.bind(this); 
 
    } 
 

 
    handleChange(event) { 
 
    this.setState({data: event.target.value}); 
 
    } 
 

 
    handleSubmit(event) { 
 
    console.log('clicked submit button'); 
 
    event.preventDefault(); 
 
    if (this.props.type === 'origin') { 
 
     console.log('inside handle submit Origin, passing: ', this.state.data); 
 
     this.props.getChildState('start', false); 
 
     this.props.getChildState('origin', this.state.data); 
 
     this.props.getChildState('renderCities', true); 
 
    } else if (this.props.type === 'cities') { 
 
     console.log('inside handle submit Cities'); 
 
     this.props.getChildState('cities', this.state.data); 
 
     this.props.getChildState('renderCities', false); 
 
     this.props.getChildState('renderQuestion', true); 
 
    } 
 

 
    } 
 

 
    render() { 
 
    return(
 
     <div className = {this.props.divName}> 
 
     <form onSubmit = {this.handleSubmit}> 
 
      <label> 
 
      {this.props.text} <br /> 
 
      <input 
 
       type="text" 
 
       placeholder={this.props.placeholder} 
 
       value={this.state.data} 
 
       onChange={this.handleChange} 
 
      /> 
 
      </label> 
 
      <input type="submit" value="Submit" /> 
 
     </form> 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
export default Form_city;

回答

2

你的方式來更新的狀態不正確,你需要使用setState,如果你想用一個新的狀態重新渲染組件:

handleContinue(answer) { 
    if (answer === 'yes'){ 
     this.setState({ 
      renderQuestion: false, 
      renderCities: true, 
      renderCities: false 
     }) 
    } 
    } 

相當不錯的解釋爲什麼:https://stackoverflow.com/a/40309023/7132340docs

+0

您的回答是正確的,我欣賞它,並將其標記爲已回答。 我想指出其他人可能有這樣的問題,那就是我「設置」狀態的方式,導致控制檯顯示的狀態發生變化。事實上,在做console.log(this.state)時,我可以看到我用this.state.cities = true所做的更改。 不知道爲什麼反應允許狀態改變,但不好處理 –

+0

我已經添加了一些與dosc和解釋的鏈接。 – Andrew

+0

@RafaelMarques準確地說,在你的第一個例子中,重點是React不處理變更。做'this.state.cities = true'只是一個普通的javascript對象屬性作用。由於React是「被動的」,它不會檢查自己狀態是否改變。使用這個。setState'會將對象修改委託給React。 React將決定是否應該放棄。 – Okazari