Boris Grunwald
Boris Grunwald

Reputation: 2712

Dynamically add classes to react component

I have the following react component

const style = {
    "border":"2px solid grey",
    "margin-bottom":"2px",
    "list-style":"none",
    "text-align":"center"
}

const isDoneStyle = {
    "text-decoration":"line-through"
}

export default function Todo({name,isComplete,date}) {

    return (
    <li style={}>
        <p>Task: {name}</p>
        <input type="checkbox" defaultChecked={isComplete}/>
        <p>{date}</p>
    </li>
    );
}

All the li's should have the style class, but only when isComplete is true it should have the isDoneStyle added. How can I achieve this?

Upvotes: 0

Views: 108

Answers (3)

Bear
Bear

Reputation: 1107

If any of above won't fulfil your requirements think about using classes instead of injecting styling directly into component. I strongly recommend using library called classnames which is designed for resolving problem like yours. I successfully used this library in many projects and it was always the best solution. Your example would like like:

CSS:

.main-layout {
    "border":"2px solid grey",
    "margin-bottom":"2px",
    "list-style":"none",
    "text-align":"center"
}

.done-layout {
    "text-decoration":"line-through"
}

React:

export default function Todo({name,isComplete,date}) {
return (
<li className={
    classNames({
       main-layout: true,
       done-layout: isComplete
    }
>
    <p>Task: {name}</p>
    <input type="checkbox" defaultChecked={isComplete}/>
    <p>{date}</p>
</li>
);
}

If you doesn't like this approach - don't worry. classNames allows you to choose one of few different ways of dynamic styles switching.

Upvotes: 0

Maciej Trojniarz
Maciej Trojniarz

Reputation: 722

You can use function to define those styles

const style = {
    "border":"2px solid grey",
    "margin-bottom":"2px",
    "list-style":"none",
    "text-align":"center"
}

const isDoneStyle = {
    "text-decoration":"line-through"
}

const getStyle = isComplete => isComplete ? {...style, ...isDoneStyle} : style

export default function Todo({name,isComplete,date}) {
    return (
    <li style={getStyle(isComplete)}>
        <p>Task: {name}</p>
        <input type="checkbox" defaultChecked={isComplete}/>
        <p>{date}</p>
    </li>
    );
}

Upvotes: 0

Cat_Enthusiast
Cat_Enthusiast

Reputation: 15688

Note that style attributes in React need to be camel-case.

const style = {
    border:"2px solid grey",
    marginBottom:"2px",
    listStyle:"none",
    textAlign:"center"
}

const isDoneStyle = {
    textDecoration:"line-through"
}

You can use a ternary operator to decide what style object to use. Additionally, you can use the spread operator, to combine the properties of the objects you want to use into a single object.

<li style={ isComplete ? {...style, ...isDoneStyle} : {...style} }>
    <p>Task: {name}</p>
    <input type="checkbox" defaultChecked={isComplete}/>
    <p>{date}</p>
</li>

Upvotes: 1

Related Questions