colin_dev256
colin_dev256

Reputation: 815

onClick an item in <li> to change colour

I am simply intending to change the color of just one item in the list. However when I click the list item, all the items in the list change to white (#ffffff). How can I achieve colour change for just that clicked item? Am I misunderstanding the calling context aka 'this'.

constructor(props) {
        super(props);

        this.state = {
            comm: '',
            editableColor: 'green',
            selected: false,
            comments: []
        }
}

updateReview = (event, key) => {
        this.setState({selected:true});
        this.state.comments[key]['comm'] ? this.setState({editableColor:'#ffffff'}) : '';
}

render() { 
       return (
                    <div className="comments">
                        <div>
                            {comments.map((value, key) => {
                                return (   
                                        <li key={key}>
                                            <div contentEditable style={{backgroundColor:this.state.editableColor}} onClick={()=>this.updateReview(value, key)}>
                                                {value['comm']}
                                            </div>
                                        </li>     
                                    );
                                })
                            }
                        </div>
                    </div>
               )
}

Upvotes: 1

Views: 4440

Answers (2)

Luke Brandon Farrell
Luke Brandon Farrell

Reputation: 511

You seem to be overcomplicating your problem. In react we use composition to break down elements, this makes individual component state easier to handle. A good rule of thumb to follow, is that if you are rendering multiple components which each need their individual and identical state, make a new component!

Here is an example of how you would achieve what you want using two components:

 class App extends React.Component {
      constructor(props) {
        super(props);

        this.state = {
          comments: [
            { comm: "First Comment" },
            { comm: "Secound Comment" },
            { comm: "Next Comment" }
          ]
        };
      }

      render() {
        return (
          <div className="comments">
            <div>
              {this.state.comments.map((value, key) => {
                return <Comment key={key} item={value} />;
              })}
            </div>
          </div>
        );
      }
    }

The app component above renders all our comments. The comment component below renders each individual comment and controls state.

class Comment extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      editableColor: "green",
      selected: false
    };
  }

  updateReview = () => {
    this.setState({ selected: true });
    this.setState({ editableColor: "#ffffff" });
  };

  render() {
    return (
      <li class="comment">
        <div
          contentEditable
          style={{ backgroundColor: this.state.editableColor }}
          onClick={() => this.updateReview()}
        >
          {this.props.item.comm}
        </div>
      </li>
    );
  }
}

Much easier to understand, no?

Here is a CodeSandbox running the code above: https://codesandbox.io/s/0xwqn27x40

I recommend you read Composition vs Inheritance on the react website. This should help you get a better understanding of how to think in React.

Upvotes: 2

shakogele
shakogele

Reputation: 399

You are setting the same value for each comment element in state. You need to put

comm: '',
editableColor: 'green',
selected: false,

inside comments[] and change the current comments color value immutably

Upvotes: 0

Related Questions