5

I am trying to add className value to list items. I map through an array of objects, and depending on the value of 'name' in the object, a differenct class would be added.

Specifically, I am trying to make a message app, if the user is 'You', the message would have class 'right' and the message is shown on the rihgt of the screen. If the user name != 'You', then the className 'left' should be given.

I've tried adding an if statement within the render part of the code, and also within the sendMessage() function to add the class when pushing the message into the array (before it is even shown on the screen). All I get are syntax errors. Please advise...

import React, { Component } from 'react';

class LandingPage extends Component {
  constructor(props) {
    // When you pass props to super, the props get assigned to 'this'
    super(props);
    // this.state is the buildiing block of the data that gets used
    this.state = {
      message: '',
      name: '',
      list: []
    }
  }

  updateInput(key, value) {
    // update react state with input data
    this.setState({
      [key]: value
    })
  }

  sendMessage() {
    const newMessage = {
      message: this.state.newMessage,
      name: 'You'
    }

    const list = [...this.state.list];

    list.push(newMessage);

    this.setState({
      list,
      newMessage: ''
    })
  }

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

      {/* messages will be listed here */}
      <div className='messagesDiv'>
        <ul>
          {/* List array is mapped through*/}
          {this.state.list.map(item => {
            return (
              <li className={item.class}>
                {item.name}: {item.message}
              </li>
            )
          })}
        </ul>
      </div>

      {/* message text area and send button here  */}
      <div className='inputDiv'>
        <form>
          <input type='text' className='input'
            value={this.message}
            onChange={e => this.updateInput('newMessage', e.target.value)}
          />
          <button className='btn btn-primary'
            onClick={() => this.sendMessage()}>Send</button>
        </form>
      </div>

    </div>
  }
}
export default LandingPage;

So above where it has {item.class}, this should either be 'right' or 'left'.

I've left just the code I think you'd need to see to diagnose my problem/ offer a solution.

Thanks.

2
  • Which syntax errors you get and in which position? Commented Nov 13, 2019 at 9:42
  • I tried adding an if statement in within the 'return' of the component and also in the sendMessage function. I get red lines all over the code, includes message of unresachable code detected, expression expected, etc. Nothing that crashes or blocks compilation of the app on local server, but no positive result. Commented Nov 13, 2019 at 9:49

4 Answers 4

3

You could use a simple function like this:

function userToClass(user){
   var userClass = '';
   if(user === 'You') {
      userClass = 'left';
   }
   else 
      userClass = 'right';
   }

   return userClass ;
}

and then use it like this:

return (
          <li className={userToClass(item.name)}>
            {item.name}: {item.message}
          </li>
        )
Sign up to request clarification or add additional context in comments.

3 Comments

Excellent. A correct answer. Thank you.I was trying so hard to get this logic within the code but that was wrong. Your solution is simple but effective - I wish I though of it!
If you want a shorter code you can use ternary operator directly in your className attribute like this: className = {(item.name === 'you' ? 'left' : 'right ')}
That's even better. Thank you.
2

Just adding a simple ternary operator will do the trick. Have a look at the example below -

{this.state.list.map(item => {
  return (
    <li className={item.name === 'You' ? 'float-left' : 'float-right'}>
      {item.name}: {item.message}
    </li>
  )
})}

Comments

0

let's assume you have a set of classes derived from your business logic, in that case, it's pretty simple.

<MyComponent className={React.addons.classSet(classes)} />;

or you can do

 <MyComponent className={classNames.join(' ')} />;

4 Comments

But the list will have an either/or, depending on the value of 'name' within the object being printed on the screen
then you can create that array of classes before applying it into the component.
But that still leaves the question of where to put the if statement, or how how to assign one of two potential classes to a dynamically produced list element. How?
create a function that will return the list of classes ses based on your logic. Reac.addons.classSet(yourFunction(params))
0

In NextJs you can try like this:

{popup_links.map((link, i) =>(
            <a
              key={link.title + i}
              href={link.href}
              className={`${styles.button} ${styles[link.customClassName]}`}
              onClick={(e) => {
                // your data
              }}
            >
              {link.title}
            </a>
          ))}

and link.customClassName is your custom class from json.

enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.