反应:在 AJAX 调用后更改组件的样式



>我目前正在创建一个动态设计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}
      />
    )
  }

相关内容

  • 没有找到相关文章

最新更新