Ghoyos
Ghoyos

Reputation: 622

How to use reacts 'onClick' to change a style.backgroundColor of an element

Ive been experimenting with react recently and would like to know how to use reacts 'onClick' syntax to change the background color of an element. The relevant pages in regards to this question are on my git hub account and both are App.js and App.css.

As you can see; Ive gotten to the point where once you 'click' the element that has the text within it 'click me!' - it calls the function boxClick(). But once that code within box click is ran it give an error -> (imgurPic) . Now if this was a vanilla js page I could easily make this work but im new to react. I would like to know how to make this function work properly and also why the current code isnt working. In my mind I have indeed defined 'boxClickCss' when I used a document.getElementsByClassName; which is why I dont understand this error.

Upvotes: 5

Views: 94120

Answers (3)

Lafi
Lafi

Reputation: 1342

I've re-factored the code so you could even see what you could do with react, in your case styled-components library helps well since it is popular and a lot used with react applications, you could compose your app into chunks of components that are reusable and reactive, that makes react very powerful. So in this example i've passed the color property to the AppWrapper directly, and each component could have it's own wrapper.

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import AppWrapper from './AppWrapper';

const Header = () => (
  <header className='headerStyle'>
    <h1>This is my React test page.</h1>
  </header>
);

const Article = ({ title, content, divClassName, handleBoxClick, color }) => (
  <div className='experimentsHolder'>
    <h2>{title}</h2>
    <p>{content}</p>
    {handleBoxClick ? (
      <div
        className={divClassName}
        onClick={() => handleBoxClick(divClassName, color)}
      >Click Me!
    </div>
    ) : <div className={divClassName}></div>}
  </div>
);

class App extends Component {
  state = {
    boxClickCss: 'white',
  }

  boxClick = (divClassName, color) => this.setState({ [divClassName]: color });

  render() {
    return (
      <AppWrapper state={this.state}>

        <Header />
        <Article
          title="Test 1"
          content="This is an example of a static view."
          divClassName="box"
        />
        <Article
          title="Test 2"
          content="This is an example of a basic css animation 'renderd' by react."
          divClassName="boxBounce"
        />
        <Article
          title="Test 1"
          content="This is an example of an onClick event 'renderd' by react."
          divClassName="boxClickCss"
          handleBoxClick={this.boxClick}
          color="red"
        />

      </AppWrapper>
    );
  }
}

export default App;

the AppWrapper:

import styled from 'styled-components';

const AppWrapper = styled.div`
  body {
    background-color:#222;
  }

  .headerStyle {
    background-color: #222;
    height: 50px;
    padding: 20px;
    color: white;
    text-align: center;
  }

  .experimentsHolder{
    background-color: teal;
    height: 200px;
    border-style: solid;
  }

  .box{
    background-color: white;
    height: 10px;
    width: 10px;
  }

  .boxBounce{
    background-color: white;
    position: relative; /*without position defined animations wont work*/
    height: 10px;
    width: 10px;
    animation: bounce 5s infinite;
  }

  .boxClickCss{
    background-color: ${({ state }) => state.boxClickCss};
    width: 70px;
  }

  @keyframes bounce {
    0% {left: 0%;}
    50% {left: 90%;}
    100% {left: 0%;}
  }
`;

export default AppWrapper;

Upvotes: 4

Sajith Edirisinghe
Sajith Edirisinghe

Reputation: 1737

In React it is a bad practise to directly manipulate the actual DOM since React changes are first applied in the virtual DOM and then only the difference is modified in the real DOM. Further, when your function is being called, there might be a chance that the DIV is not actually present in the real DOM.

You can find out more about the lifecycle of a React component and how you can manipulate the component behaviour and appearance at each lifecycle stage by reading the official documentation.

However, as for your problem, you need to use the state to change the color of the DIV. Below is the code (Only the modified part is included.)

class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      bgColor: ""
    }
  }


  boxClick = (e) => {
    this.setState({
      bgColor: "red"
    })
  }

  render() {
    return (
      <div className="App">


        <article className='experimentsHolder'>
          <h2>Test 3</h2>
          <p>This is an example of an onClick event 'renderd' by react.</p>
          <div className="boxClickCss" 
          style={{backgroundColor: this.state.bgColor}}
           onClick={this.boxClick}>Click Me!</div>
        </article>

      </div>
    );
  }
}

Here is a working example

https://codesandbox.io/embed/0p1zmpk4yl

Upvotes: 12

Adeel Imran
Adeel Imran

Reputation: 13986

You can do something like this

class SampleApp extends React.Component {
  state = {
    color: 'red'
  }
  onChange = () => {
     this.setState({ color: 'green' });
  }
  render () {
    return (
      <div 
       style={{ backgroundColor: this.state.color }} 
       onClick={this.onChange}
      >
        <p>Some content goes here</p>
        <p>Some other content</p>
      </div>
    );
  }
}

Have a state color which is by default the color you want, and onClick event trigger a method which updates the color state and re-renders your UI based on it.

Upvotes: 3

Related Questions