繁体   English   中英

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

[英]React: Change Style of component after AJAX Call

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

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。 那可能吗?

您可以使用三元运算符根据状态更改显示MainButton。 检查下面的代码,这里我采用了新的状态变量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} /> ) } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM