React 渲染函数一直被调用
React render function keeps being called
我的 React 应用程序中的渲染函数一直被调用,这导致了问题。我有一个显示一些状态对象的函数,但它失败了,因为它一直被调用。至少那是我认为正在发生的事情。
其他错误包括未捕获的承诺和更新未安装组件的状态。我认为这些只是不断重新渲染的症状,但我不能确定。我已经在下面粘贴了所有相关代码,希望有人能弄明白并帮助我。
代码
import React, { Component } from 'react';
import './style.css';
import { FlexyFlipCard } from 'flexy-flipcards';
import Bingo from '../utils/Bingo';
class Card extends Component {
constructor(props) {
super();
console.log('constructor - This happens 1st.');
this.state = {
loading: 'initial',
data: '',
card: {},
tiles: {}
};
}
componentWillMount() {
console.log('componentWillMount - This happens 2nd.');
this.setState({ profile: {} });
const { userProfile, getProfile } = this.props.auth;
if (!userProfile) {
getProfile((err, profile) => {
this.setState({
profile,
loading: 'profile'
});
});
} else {
this.setState({ profile: userProfile });
}
}
componentDidMount() {
console.log('componentDidMount - This happens 5th.');
const cardId = 14;
this.setState({ loading: 'true' });
this.fetchCard(cardId)
.then((card) => {
console.log('componentDidMount - This happens 9th.');
this.setState({ tiles: card }, function() {
this.setState({ loading: 'complete' })
});
});
}
fetchCard(cardId) {
const promise = new Promise((resolve, reject) => {
Bingo.getTiles(cardId).then(card => {
console.log('fetchCard - This happens 8th (after Bingo.getTiles).');
resolve(card);
});
});
console.log('fetchCard - This happens 6th.');
return promise;
}
renderCards() {
console.log('renderCards');
if (this.state.tiles.length > 0) {
return this.state.tiles.map(tile => {
return (
<div
className="item"
key={tile[0].id}>
<FlexyFlipCard
frontBackgroundColor="#000034"
backBackgroundColor="#000034"
>
<div ref="flipper">
<h3>{tile[0].name}</h3>
<br />
<button className="select">Select artist</button>
</div>
<div>
<h4>
<input type="radio"
name="artist1"
value={tile[0].artist_1}
/>
{tile[0].artist_1}
<br />
<br />
<input type="radio"
name="artist2"
value={tile[0].artist_2}
/>
{tile[0].artist_2}
<br />
<br />
<input type="radio"
name="artist3"
value={tile[0].artist_3}
/>
{tile[0].artist_3}
<br />
<br />
<div ref="flipper">
<button className="select"
onClick={this.submitArtist}>
Save artist
</button>
</div>
</h4>
</div>
</FlexyFlipCard>
</div>
);
});
}
}
render() {
console.log('render - This happens 3rd - after componentWillMount');
const { profile } = this.state;
if (this.state.loading === 'initial') {
console.log('render - This happens 4th - after the class is constructed.');
return <h2>Intializing...</h2>;
}
if (this.state.loading === 'true') {
console.log('render - This happens 7th - when waiting for data.');
return (
<div className="Card">
<h2>Preparing your bingo card - please wait one moment</h2>
</div>
);
}
if (this.state.loading === 'complete') {
console.log('render - This happens when???');
return (
<div className="Card">
<h2>{profile.nickname + String.fromCharCode(39)}s Radio Bingo Board</h2>
<div className="tileCard">
<div className="item-list">
{this.renderCards()}
</div>
</div>
</div>
);
}
console.log('render - This happens 8th - after I get data.');
return (
<div className="Card">
Blank space
</div>
);
}
}
export default Card;
每次您使用 setState 时它都会呈现。好吧,并非总是如此,有时 React 会一次执行多个 setState 操作。
我无法读取所有的错误,但第一个是因为在 object 不存在的那一刻呈现页面,所以它说无法读取 属性 未定义的 id。你可以在渲染之前询问 id object 先存在。例如。如果(标题)title.id等
如果您需要向用户显示的所有步骤,那么您必须假设 object 在某些情况下不存在,并且您始终必须在调用 属性.
问题是我的提取响应是对象而不是数组,所以我无法通过它进行映射。错误消息让我认为渲染调用次数过多是个问题。
这段简单的代码通过将 JSON 送入数组纠正了这个问题。可惜我花了大约一周的时间才弄明白。
Bingo.getTiles(cardId).then(response => {
const card = Object.keys(response).map((index) => {
const tile = [];
tile.push(response[index]);
return tile;
});
我的 React 应用程序中的渲染函数一直被调用,这导致了问题。我有一个显示一些状态对象的函数,但它失败了,因为它一直被调用。至少那是我认为正在发生的事情。
其他错误包括未捕获的承诺和更新未安装组件的状态。我认为这些只是不断重新渲染的症状,但我不能确定。我已经在下面粘贴了所有相关代码,希望有人能弄明白并帮助我。
代码
import React, { Component } from 'react';
import './style.css';
import { FlexyFlipCard } from 'flexy-flipcards';
import Bingo from '../utils/Bingo';
class Card extends Component {
constructor(props) {
super();
console.log('constructor - This happens 1st.');
this.state = {
loading: 'initial',
data: '',
card: {},
tiles: {}
};
}
componentWillMount() {
console.log('componentWillMount - This happens 2nd.');
this.setState({ profile: {} });
const { userProfile, getProfile } = this.props.auth;
if (!userProfile) {
getProfile((err, profile) => {
this.setState({
profile,
loading: 'profile'
});
});
} else {
this.setState({ profile: userProfile });
}
}
componentDidMount() {
console.log('componentDidMount - This happens 5th.');
const cardId = 14;
this.setState({ loading: 'true' });
this.fetchCard(cardId)
.then((card) => {
console.log('componentDidMount - This happens 9th.');
this.setState({ tiles: card }, function() {
this.setState({ loading: 'complete' })
});
});
}
fetchCard(cardId) {
const promise = new Promise((resolve, reject) => {
Bingo.getTiles(cardId).then(card => {
console.log('fetchCard - This happens 8th (after Bingo.getTiles).');
resolve(card);
});
});
console.log('fetchCard - This happens 6th.');
return promise;
}
renderCards() {
console.log('renderCards');
if (this.state.tiles.length > 0) {
return this.state.tiles.map(tile => {
return (
<div
className="item"
key={tile[0].id}>
<FlexyFlipCard
frontBackgroundColor="#000034"
backBackgroundColor="#000034"
>
<div ref="flipper">
<h3>{tile[0].name}</h3>
<br />
<button className="select">Select artist</button>
</div>
<div>
<h4>
<input type="radio"
name="artist1"
value={tile[0].artist_1}
/>
{tile[0].artist_1}
<br />
<br />
<input type="radio"
name="artist2"
value={tile[0].artist_2}
/>
{tile[0].artist_2}
<br />
<br />
<input type="radio"
name="artist3"
value={tile[0].artist_3}
/>
{tile[0].artist_3}
<br />
<br />
<div ref="flipper">
<button className="select"
onClick={this.submitArtist}>
Save artist
</button>
</div>
</h4>
</div>
</FlexyFlipCard>
</div>
);
});
}
}
render() {
console.log('render - This happens 3rd - after componentWillMount');
const { profile } = this.state;
if (this.state.loading === 'initial') {
console.log('render - This happens 4th - after the class is constructed.');
return <h2>Intializing...</h2>;
}
if (this.state.loading === 'true') {
console.log('render - This happens 7th - when waiting for data.');
return (
<div className="Card">
<h2>Preparing your bingo card - please wait one moment</h2>
</div>
);
}
if (this.state.loading === 'complete') {
console.log('render - This happens when???');
return (
<div className="Card">
<h2>{profile.nickname + String.fromCharCode(39)}s Radio Bingo Board</h2>
<div className="tileCard">
<div className="item-list">
{this.renderCards()}
</div>
</div>
</div>
);
}
console.log('render - This happens 8th - after I get data.');
return (
<div className="Card">
Blank space
</div>
);
}
}
export default Card;
每次您使用 setState 时它都会呈现。好吧,并非总是如此,有时 React 会一次执行多个 setState 操作。
我无法读取所有的错误,但第一个是因为在 object 不存在的那一刻呈现页面,所以它说无法读取 属性 未定义的 id。你可以在渲染之前询问 id object 先存在。例如。如果(标题)title.id等
如果您需要向用户显示的所有步骤,那么您必须假设 object 在某些情况下不存在,并且您始终必须在调用 属性.
问题是我的提取响应是对象而不是数组,所以我无法通过它进行映射。错误消息让我认为渲染调用次数过多是个问题。
这段简单的代码通过将 JSON 送入数组纠正了这个问题。可惜我花了大约一周的时间才弄明白。
Bingo.getTiles(cardId).then(response => {
const card = Object.keys(response).map((index) => {
const tile = [];
tile.push(response[index]);
return tile;
});