Search code examples
javascriptreactjsonclicksetstate

React JS How to change font color in element other than clicked button onClick?


So I have managed to change the background color of a button using setState() within that button. However, I am trying to use that button to change the font color of list elements within the same component.

Using setState() only lets me change the element I am clicking. I've tried querySelecting the class of the other elements, but using left.setState() is not a valid function.

How can I change the CSS properties of an element using an onClick function of a button?

import React, { Component } from 'react';
import firebase from 'firebase';
import { firebaseConfig } from './connection';

// Initialize Firebase
firebase.initializeApp(firebaseConfig);
let messageRef = firebase.database().ref('messages');

class LandingPage extends Component {

  constructor(props) {
    super(props);

    this.state = {
      name: '',
      message: '',
      list: [],
      font: "black",
      color: "blue"
    }
  }

//   onChange = () => {
//     if (this.state.color == 'blue'){
//       this.setState({ color: 'green' });
//     }
//     else {
//       this.setState({ color: 'blue' });
//     }
//  }

 onChange = () => {
  var left = document.querySelectorAll(".left");
  if (this.state.color === 'black'){
    this.setState({ color: 'grey' });
  }
  else {
    this.setState({ color: 'black' });
  }
}

  render() {
    return <div className='container'>

      {/* title */}
      <div className='titleDiv'>
        <h1>React Message App</h1>
      </div>

      {/* messages will be listed here */}
      <div className='messagesDiv' id='messagesDivId'>
        <ul>
          {/* List array is mapped through*/}
          {this.state.list.map(item => {
            return (
              <li className={(item.name === this.state.name ? 'right' : 'left')}
              style={{ color: this.state.font }}
                key={item.id}
                id={item.id}>
                {item.name}: {item.message}
              </li>
            )
          })}
        </ul>
      </div>

      {/*think, delete options*/}

      <button className='button think' style={{ backgroundColor: this.state.color }} onClick={this.onChange}>Think...</button>

      <button className='button delete'>Delete last message</button>
    </div>
  }
}

export default LandingPage;

It is the 'think' button which should be clicked to change the list elements with a 'left' or 'right' class name. Please advise...


Solution

  • You messed up some variable names and misunderstood how React works.

    First, you can't query and HTML element and execute setState because this is a React function. This function is not accessible from within the HTML document.

    Second, your first approach with changing a state variable with the button click and mapping this variable to the color of the list elements is correct, but you mixed up the names:

    This is your onChangeMethod:

    onChange = () => {
        if (this.state.color == 'blue'){
            this.setState({ color: 'green' });
        }
        else {
            this.setState({ color: 'blue' });
        }
    }
    

    Here you are mapping the state variable to the color property:

    <li className={(item.name === this.state.name ? 'right' : 'left')}
        style={{ color: this.state.font }}
        key={item.id}
        id={item.id}>
        {item.name}: {item.message}
    </li>
    

    You are setting state.color in theonChange function, but you are referencing state.font in you list element, instead change style to the following:

    style={{ color: this.state.color }}