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

时间:2018-01-26 04:13:32

标签: javascript css laravel reactjs styles

我目前正在创建动态设计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。这可能吗?

2 个答案:

答案 0 :(得分:0)

您可以使用三元运算符根据状态更改显示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 

OR

如果您希望在收到回复之前保持按钮处于停用状态,请尝试使用以下按钮。

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 

答案 1 :(得分:0)

  • 以下是问题: mainColor和fontColor是MainButton的构造函数中的init。 构造函数只能初始化一次,因此这两个动态字段永远不会是动态的。
  • 这是解决方案: 将样式移动到渲染功能,以便在数据更改时颜色可以是动态的。
  • 提示:查看反应文档https://reactjs.org/docs/state-and-lifecycle.html

&#13;
&#13;
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}
      />
    )
  }
&#13;
&#13;
&#13;