1

Im trying to change class name of an element dynamically yet not successful. Here is my attempt

this.state = {
   element: [<div className="changeMe"></div>]     
}

changeClassName(){
    let tmp = this.state.element[0]

    tmp.className="new class name"


   this.setState({element[0]: tmp})
}

render(){
   return(

    <Button onClick={this.changeClassName()}>Change the class name</Button>
   )
}

Any suggestions?

Kai
  • 2,529
  • 1
  • 15
  • 24
  • 1
    Possible duplicate of [ReactJS add dynamic class to manual class names](https://stackoverflow.com/questions/36209432/reactjs-add-dynamic-class-to-manual-class-names) – Nino Filiu Feb 22 '19 at 23:44

3 Answers3

0

Instead of storing JSX in your state you could have a state variable that contains your className string that you use in the render method. changeClassName would then just be responsible for changing this string in state.

Example

class App extends React.Component {
  state = {
    className: "changeMe"
  };

  changeClassName = () => {
    this.setState(prevState => ({
      className: prevState.className === "changeMe" ? "newClassName" : "changeMe"
    }));
  };

  render() {
    const { className } = this.state;

    return (
      <div className={className}>
        <button onClick={this.changeClassName}>
          Change the class name ({className})
        </button>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>
Tholle
  • 108,070
  • 19
  • 198
  • 189
  • the soulution is mission `element: [
    ]`
    –  Feb 22 '19 at 23:42
  • i need to change class name of div found in element –  Feb 22 '19 at 23:42
  • 1
    @toymoy It's generally not a good idea to store React elements (JSX) directly in state. It's better to store data in state and derive your JSX from that in the render method. There is no way for you to structure your app like that instead? – Tholle Feb 22 '19 at 23:44
0

Assuming you are using the latest version of React, please see this for a solution:

https://codesandbox.io/s/5kkwqvvopk?codemirror=1&fontsize=14

EDIT: If you are not using the latest version of react, and cannot use hooks, instead make sure your react component is a class, and use this.setState to store the class name you want.

JSager
  • 1,420
  • 9
  • 18
0

Lots of problems here.

1) You are immediately invoking your function in your onClick. This will be evaluated - you need to make sure what you pass to onClick is a function, not the invocation of a function.

2) changeClass name won't be bound to the instance of the class this is in. When you do eventually get to invoke it from clicking the button, this won't be what you expect, so setState is unlikely to work. You can use an arrow function like syntax to solve this if you're using create-react-app.

3) You can't change a className of a JSX element like that - you are far better off inserting it with Javascript for the transpiler to deal with.

Here's a possible solution:

state = {
 className: "changeMe"
};

changeClassName = (newName) => {
  this.setState({
    className: newName
  });
};

render() {
  const { className } = this.state;

  return (
    <div className={className}>
      <button onClick={() => this.changeClassName('whatever you want')}>
        Use whatever variable in the arg above you like. Notice how I have passed in anonymous func, which will invoke my method for me.
      </button>
    </div>
 );
}