>我目前正在创建一个动态设计UI。我也在使用 axios 调用来获取动态设计属性,如背景颜色、字体颜色、要显示的图像。
import React, {Component} from "react";
import MainButton from '../utilities/MainButton';
const tinycolor = require("tinycolor2");
const styles = {
underlineStyle: {
borderColor: blue800
}
}
class MobileHome extends React.Component {
constructor(props) {
super(props);
this.color = '';
this.state = {
mainColor: '',
fontColor: ''
}
}
componentWillMount() {
axios.get('/getEventConfig').then(res => {
var config = res.data;
var color = tinycolor(config.COLOR);
var font = '#fff';
if (color.isLight()){
font = '#000';
}
this.color = color;
this.setState({mainColor: config.COLOR}); // error on timing issue
console.log('set state', this.state.mainColor);
});
}
render() {
return (
<div className="center-panel">
<TextField
hintText="Enter Code Here"
fullWidth={true}
underlineFocusStyle={styles.underlineStyle}
id="event_code" />
<MainButton
label="Upload Photo"
fullWidth={true}
size="xl"
color={color}
fontcolor={this.state.fontColor}
onClick={this.uploadPhoto}/>
</div>
)
}
}
export default MobileHome
在其上,我的 MainButton 是另一个组件,只是调用 Material UI raiisedButton:
class MainButton extends React.Component {
constructor(props) {
super(props);
console.log('p', this.props);
let mainColor = _.isNil(this.props.color) ? '#2E65C2': this.props.color;
let fontColor = _.isNil(this.props.fontColor) ? '#FFF': this.props.fontColor;
this.styles = {
root: {
width: 225
},
label: {
color: fontColor,
paddingTop: 5
},
color: mainColor,
}
}
render() {
return (
<RaisedButton
label={this.props.label}
fullWidth={this.props.fullWidth}
buttonStyle={this.styles.button}
style={this.styles.root}
backgroundColor={this.styles.color}
labelStyle={this.styles.label}
onClick={this.props.onClick}
/>
)
}
}
export default MainButton;
问题是,在 axios 调用完成之前,MainButton 就已经渲染了。我正在寻找某种方法,让渲染在 axios 调用完成之前等待,在它显示 UI 之前。这可能吗?
您可以使用三元运算符根据状态更改显示主按钮。检查下面的代码,这里我采用了新的状态变量 resReceived 并将其默认设置为 false。在 API res 设置为 true 中。
import React, {Component} from "react";
import MainButton from '../utilities/MainButton';
const tinycolor = require("tinycolor2");
const styles = {
underlineStyle: {
borderColor: blue800
}
}
class MobileHome extends React.Component {
constructor(props) {
super(props);
this.color = '';
this.state = {
mainColor: '',
fontColor: '',
resReceived: false
}
}
componentWillMount() {
axios.get('/getEventConfig').then(res => {
var config = res.data;
var color = tinycolor(config.COLOR);
var font = '#fff';
if (color.isLight()){
font = '#000';
}
this.color = color;
this.setState({mainColor: config.COLOR, resReceived: true}); // error on timing issue
console.log('set state', this.state.mainColor);
});
}
render() {
return (
<div className="center-panel">
<TextField
hintText="Enter Code Here"
fullWidth={true}
underlineFocusStyle={styles.underlineStyle}
id="event_code" />
{this.state.resReceived ?
<MainButton
label="Upload Photo"
fullWidth={true}
size="xl"
color={color}
fontcolor={this.state.fontColor}
onClick={this.uploadPhoto}/>
: ''}
}
</div>
)
}
}
export default MobileHome
或
如果要在收到响应之前保持按钮禁用状态,请尝试下面的按钮。
import React, {Component} from "react";
import MainButton from '../utilities/MainButton';
const tinycolor = require("tinycolor2");
const styles = {
underlineStyle: {
borderColor: blue800
}
}
class MobileHome extends React.Component {
constructor(props) {
super(props);
this.color = '';
this.state = {
mainColor: '',
fontColor: '',
disableMainButton: true
}
}
componentWillMount() {
axios.get('/getEventConfig').then(res => {
var config = res.data;
var color = tinycolor(config.COLOR);
var font = '#fff';
if (color.isLight()){
font = '#000';
}
this.color = color;
this.setState({mainColor: config.COLOR, disableMainButton: false}); // error on timing issue
console.log('set state', this.state.mainColor);
});
}
render() {
return (
<div className="center-panel">
<TextField
hintText="Enter Code Here"
fullWidth={true}
underlineFocusStyle={styles.underlineStyle}
id="event_code" />
<MainButton
label="Upload Photo"
fullWidth={true}
size="xl"
color={color}
fontcolor={this.state.fontColor}
onClick={this.uploadPhoto}
disabled = {this.state.disableMainButton}
/>
}
</div>
)
}
}
export default MobileHome
- 这是问题所在:mainColor 和 fontColor 是 MainButton 构造函数中的 init。构造函数只能初始化一次,因此这两个动态字段永远不可能是动态的。
- 这是解决方案:移动样式以呈现功能,以便在数据更改时颜色可以是动态的。
- 提示:查看反应文档 https://reactjs.org/docs/state-and-lifecycle.html。
render() {
const { fontColor, mainColor } = this.props;
const styles = {
root: {
width: 225
},
label: {
color: _.isNil(this.props.fontColor) ? '#FFF': fontColor,
paddingTop: 5
},
color: _.isNil(this.props.color) ? '#2E65C2': mainColor,
}
return (
<RaisedButton
label={this.props.label}
fullWidth={this.props.fullWidth}
buttonStyle={styles.button}
style={styles.root}
backgroundColor={styles.color}
labelStyle={styles.label}
onClick={this.props.onClick}
/>
)
}