Svetoslav Dimitrov
Svetoslav Dimitrov

Reputation: 929

Change style in JSS

I have the following component using JSS:

import React from 'react'
import injectSheet from 'react-jss'

const styles = {
  button: {
    backgroundColor: 'pink',
  }
}

class App extends Component {
    changeStyle = () => {
         styles.button.backgroundColor: 'blue' //this obviously doesn't work
    }
    render() {
        return (
            <div className="App">
                <button className={this.props.classes.button} onClick={this.changeStyle}>Switch user</button>
            </div>
        );
    }
}

This is definitely a simple question. When I click button I expect that background will change to 'blue', but just assigning new color doesn't work.

Upvotes: 3

Views: 5646

Answers (3)

franksands
franksands

Reputation: 2085

With JSS version 7.1.7+, you can use function values to define your styles.

const styles = {
  button: {
    color: data => data.color
  }
}

when you need to change the color, call the update method of the sheet prop:

this.props.sheet.update({
  button: {
    color: 'red',
  }
})

Please note that as of August, 2018 there are limitations to using function values

Upvotes: 0

Steve Banton
Steve Banton

Reputation: 2498

Conditional Styles in JSS

In JSS you should be using a function to inject style names (as strings) into the component. I assume you're using injectSheet to inject classes into the props, and just left that out of your code sample. injectSheet will inject the classes object that contains key value pairs like so: [styleObjectPropertyName]: [dynamicInjectedCSSPropertyName], and it will inject the CSS into the header of the page.

When you try to edit the style object after this happens, it is not reactive, so you need to prepare your CSS styles beforehand and remove or apply them dynamically in the code.

classNames package

You can use a simple library like classNames to conditionally apply styles, which is the way I've outlined below.

import React from 'react';
import injectSheet from 'react-jss';

const styles = {
  buttonPink: {
    backgroundColor: 'pink',
  },
  buttonBlue: {
    backgroundColor: 'blue',
  },
};

class App extends Component {
  state = {
    isButtonColorPink: true,
  };

  changeButtonColor = () => {

  }

  render() {
    const { buttonColorPink } = this.state;
    const { classes } = this.props;
    return (
      <div className="App">
        <button className={classNames({ 
          [classes.buttonPink]: isButtonColorPink,
          [classes.buttonBlue]: !isButtonColorPink,
        })} onClick={this.toggleStyle}>Switch user</button>
      </div>
    );
  }
}

export default injectSheet(styles)(App);

Alternatively you can just use inline styling for any dynamic styling - something like style={{ backgroundColor: this.state.buttonColor }} inside the button, and simply change buttonColor property with a thisState inside a class method.

Upvotes: 3

Teedub
Teedub

Reputation: 382

The ideal pattern is to store the color of the button in a state object, then update that state when you want to change the color.

One solution to your problem is something like this:

import React from 'react'
import injectSheet from 'react-jss'


class App extends Component {

  constructor(props) {
    super(props);
    this.state = {buttonColor: 'pink'};

  }
    changeStyle = (color) => {
      this.setState({
        buttonColor: color
      });
    }

    render() {
        return (
            <div className="App">
                <button className={this.props.classes.button} onClick={ this.changeStyle }>Switch user</button>
            </div>
        );
    }
}

Upvotes: -1

Related Questions