反应 - 条件渲染失败,尝试第二次显示组件

问题描述:

我正在创建一个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;

你的方式来更新的状态不正确,你需要使用setState,如果你想用一个新的状态重新渲染组件:

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

相当不错的解释为什么:https://*.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