0

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?

2
  • Hi Boris, just wrote you a solution below, let me know if that helps. Commented Sep 2, 2019 at 8:34
  • Hi Boris, I've wrote a solution which is based on defining a function which will calculate the style base on the prop. Have you tried it? Commented Sep 2, 2019 at 8:37

3 Answers 3

1

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>
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you. The style actually still works even though I don't use camel case.
I am using nextJs, maybe that is why?
@BorisGrunwald that explains alot haha. That's awesome. Did the above work for you?
@BorisGrunwald great! For the record, I think it would make more sense to create a class in your style sheet instead though and refer to that class conditionally. It's just cleaner overall. Please do consider upvoting and marking this as the answer as well :)
0

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>
    );
}

Comments

0

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.

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.