React - 条件渲染失败尝试第二次显示组件
React - conditional render fails trying to display component for the second time
我正在创建一个 React 组件来管理用户输入。
此组件 UserInput.js 具有以下方法,
renderOrigin - 显示一个 Form 组件,
renderCities - 显示具有不同道具的相同表单组件,
renderAddCitiesQuestion - 呈现两个由
处理的按钮(是或否)
handleContinue - 使用 'continue' 问题的答案设置状态
getChildSate - 设置子组件接收的状态(如表单)
render - 基于状态的条件渲染。状态具有布尔属性,'start'(第一次渲染),'rendercities' 和 'renderQuestion'.
条件的流程如下。
首先,state.start 为真,我们调用 renderOrigin;
然后,state.start 变为假,state.renderCities 变为真,我们调用 renderCities();然后,state.rendercities 变为假,state.renderQuestion 变为真,这让我们调用 renderAddCityQuestion();现在有两种可能性,要么用户点击否按钮,我们不应该渲染任何东西,要么他点击是并且 state.renderCities 变为真(并且 state.renderQuestion 变为假)调用 renderCities() (并且它被调用,我通过 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;
为了完整起见,这里还有 Form 组件。
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
})
}
}
很好的解释原因:
还有 docs.
我正在创建一个 React 组件来管理用户输入。 此组件 UserInput.js 具有以下方法,
renderOrigin - 显示一个 Form 组件,
renderCities - 显示具有不同道具的相同表单组件,
renderAddCitiesQuestion - 呈现两个由
处理的按钮(是或否)handleContinue - 使用 'continue' 问题的答案设置状态
getChildSate - 设置子组件接收的状态(如表单)
render - 基于状态的条件渲染。状态具有布尔属性,'start'(第一次渲染),'rendercities' 和 'renderQuestion'.
条件的流程如下。 首先,state.start 为真,我们调用 renderOrigin; 然后,state.start 变为假,state.renderCities 变为真,我们调用 renderCities();然后,state.rendercities 变为假,state.renderQuestion 变为真,这让我们调用 renderAddCityQuestion();现在有两种可能性,要么用户点击否按钮,我们不应该渲染任何东西,要么他点击是并且 state.renderCities 变为真(并且 state.renderQuestion 变为假)调用 renderCities() (并且它被调用,我通过 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;
为了完整起见,这里还有 Form 组件。
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
})
}
}
很好的解释原因: