反应 - 条件渲染失败,尝试第二次显示组件
我正在创建一个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/7132340 和docs。
您的回答是正确的,我欣赏它,并将其标记为已回答。 我想指出其他人可能有这样的问题,那就是我“设置”状态的方式,导致控制台显示的状态发生变化。事实上,在做console.log(this.state)时,我可以看到我用this.state.cities = true所做的更改。 不知道为什么反应允许状态改变,但不好处理 –
我已经添加了一些与dosc和解释的链接。 – Andrew
@RafaelMarques准确地说,在你的第一个例子中,重点是React不处理变更。做'this.state.cities = true'只是一个普通的javascript对象属性作用。由于React是“被动的”,它不会检查自己状态是否改变。使用这个。setState'会将对象修改委托给React。 React将决定是否应该放弃。 – Okazari