React JSX in className if-else syntax [duplicate] - javascript

This question already has answers here:
if-else statement inside jsx: ReactJS
(17 answers)
Closed 4 years ago.
I am currently working on a react app where I am adding and changing classes based on certain state changes. It worked successfully in testing with a ternary operator but now I realized I will have to add mutiple else-if statements so I am trying to convert it to a classic if else format but am getting syntax errors and I'm not sure how to do it.
Here is the ternary operator that worked fine:-
<div className={"wrapper " + (this.state.hot ? 'wrapper-gradient-hot' : 'wrapper-gradient-cold')}>
Here is my attempt to make it a classic if-else in JSX and failed:-
<div className={"wrapper " + (
if (this.state.hot) {
return 'wrapper-gradient-hot';
} else {
return 'wrapper-gradient-cold';
}
)}>
Pls help me out :)

You can only use expressions inside of a React Component attribute. You'll need to move your logic into a function.
function temperatureClassname(temp){
const prefix = 'wrapper-gradient-'
switch (temp) {
case 'hot': return prefix + 'hot'
case 'cold': return prefix + 'cold'
case 'ice-cold': return prefix + 'too-cool'
}
}
And your react component would look like this:
<div className={ temperatureClassname(this.state.hot) }>

If and else statements, are just that... statements. Inline JSX expressions that you wrap with {…} only allow expressions; statements are not expressions.
Your ternary approach is fine, though since there's some commonality between the two strings you can actually use interpolation:
<div className={`wrapper-gradient-${this.state.hot ? 'hot' : 'cold'}`}>

One approach you could adopt is to handle this outside of your JSX. So, in your render function still but just above where you return.
render() {
let gradientValue;
// Put your if-else here and update gradientValue on each condition.
return (
<h1 className=`wrapper ${gradientValue}`>Your html here</h1>
);
}

return only returns values from inside a function, just putting parentheses around an if/else statement like that isn't going to work. You'd be better off sticking with the ternary operator, and nesting them as required.

Related

Can i use multiple line in ternary operator

I want to use the if else statement in the ternary operator
if (open) {
setOpen(false)
} else {
setOpen(true)
navigator.clipboard.writeText(link)
}
There is no problem in "if" I cant figuring out how to convert else to ternary. Like something the code below:
open ? setOpen(false) : setOpen(true) ; navigator.clipboard.writeText(link)
Something like this or is there another method to do the job?
Don't.
You're trying to use the ternary conditional operator for the wrong reason. It is not a drop-in replacement for any if block.
The ternary conditional operator is an expression. It resolves to a value, which can be used elsewhere. For example:
let x = someCondition ? 1 : 0;
The expression resolves to a value, either 1 or 0, and that value is used in an assignment statement.
The code you're showing is not an expression. What you have is a series of statements, conditionally executed based on some value. An if block is a structure for conditionally executing statements.
The code you have now is correct.
Yes, it's possible to write multiple statements in ternary if else cases:
The format is:
condition ? codeLine1 : ( codeLine2 , codeLine3 )
Which makes your statement as:
open ? setOpen(false) : (setOpen(true), navigator.clipboard.writeText(link));
Combine multiple statements in parenthesis separated by commas in between each line.
That being said it's recommended to use old fashioned way of if-else statement if multiple statements are involved.
Please select answer if it helps and let me know if any questions.
Yes. it is possible (although not a best practice and not recommended)
they way to to it is by:
Put everything inside parenthesis
Seperate each statement with comma (",")
e.g:
condition ? statement1 : ( statement2, statement3, statement4 )
Try this snippet:
let a = 1;
let b = 1;
a == b ?
(console.log("they"),console.log("are"), console.log("equal")) :
(console.log("they're"), console.log("not equal"));

is there a way to turn if statement in a switch statement? [duplicate]

This question already has answers here:
Is it possible to use .contains() in a switch statement?
(2 answers)
Closed 2 years ago.
I've got this code
if (header.classList.contains("capricorn")) {
//star sign description
para.innerHTML = starSign.Capricorn;
} else if (header.classList.contains("aquarius")) {
para.innerHTML = starSign.Aquarius;
} else if (header.classList.contains("pisces")) {
para.innerHTML = starSign.Pisces;
I want to turn it in a switch statement, is that possible?
Consider parameterizing your checks instead, based on the properties of starSign object:
function chooseSign(classList, signs) {
return signs.find(s => classList.contains(s.toLowerCase());
}
... and using it accordingly:
const sign = chooseSign(header.classList, Object.keys(starSign));
if (sign) {
para.innerHTML = starSign[sign];
}
I assumed starSign is a collection of texts with only 12 keys. If that's not the case, consider making a separate array out of those.
In general, when you have a looooong series of if - else if - else if checks doing essentially the same stuff over and over, think about using separate function for the same purpose. Not only this gives you a chance to simplify the code (like in this example), but also isolates the business logic decision making your code both more readable and more testable.

Ternary operator multiple statements [duplicate]

This question already has answers here:
Javascript - Ternary Operator with Multiple Statements
(5 answers)
Closed 3 years ago.
I want to do multiple things if the condition is true or false. I tried to wrap the statements in a { } but it doesn't work. So my code:
theId == this.state.correctId ?
console.log("Correct Id!") :
console.log("TRY AGAIN")
I tried:
theId == this.state.correctId ?
{console.log("Correct Id!"); //semicolon does not make any difference
this.setState({counter: this.state.counter+1})
} :
console.log("TRY AGAIN")
This doesn't work. How do I add multiple statements if the condition is true or false?
Thanks.
The conditional operator should only be used when you need to come up with an expression that is (conditionally) one thing or another, eg
const something = cond ? expr1 : expr2;
Because that's not the case here (and you want to log or call setState), the conditional operator is not appropriate; use if/else instead:
if (theId == this.state.correctId) {
console.log("Correct Id!")
this.setState({counter: this.state.counter+1});
} else {
console.log("TRY AGAIN");
}
You could technically slightly tweak your original code by using the comma operator to combine expressions:
theId == this.state.correctId
? (
console.log("Correct Id!"),
this.setState({counter: this.state.counter+1})
)
: console.log("TRY AGAIN");
But that's very hard-to-read, and is not what a reader of your code would expect to see from the conditional operator, so should probably be avoided.
Using the conditional operator when the resulting expression is not going to be used should probably be reserved only for code-golfing and minifying, but not in professional source code, where readability is extremely important.
You can use the comma operator, like this:
const ret = true ?
(console.log("1"),
console.log("2"),
"3")
: console.log("nope");
console.log(ret);

ReactJs SyntaxError with ternary operator

Below code shows syntax error in ReactJs component:
(that.props.actionType == "opinion")
?
{that.state._CmtCnt?<ViewAnswer isFullView={that.props.isFullView?true:false} />:null}
:
{that.state._CmtCnt?<ViewComment isFullView={that.props.isFullView?true:false} />:null}
Basic Syntax is:
condition? expression1 : expression2
This is because you are using {} with expression1 and expression2, remove that, {} is required when we want to put JS expressions inside JSX. The way you are using, it means you are trying to return an object and error is because key is not valid.
Write it like this:
(that.props.actionType == "opinion") ?
(that.state._CmtCnt?<ViewAnswer isFullView={that.props.isFullView?true:false} />:null)
:
(that.state._CmtCnt?<ViewComment isFullView={that.props.isFullView?true:false} />:null)
You need to use normal parenthesis for grouping. Braces work only within jsx expressions.
that.props.actionType == "opinion"
? (that.state._CmtCnt ? <ViewAnswer isFullView={that.props.isFullView} /> : null)
// ^ ^
: (that.state._CmtCnt ? <ViewComment isFullView={that.props.isFullView} /> : null)
// ^ ^
You should write easier to understand code rather than complex nested terinary with little changes between them - all you choose is pick up a component to use, so move that up and you end up with easier to read code with less logic inside JSX
const Renderer = that.props.actionType == "opinion" ? ViewAnswer : ViewComment
// ...
{that.state._CmtCnt && <Renderer isFullView={!!that.props.isFullView} />}
// or
{that.state._CmtCnt ?
<Renderer isFullView={!!that.props.isFullView} /> :
null
}
not sure why you are using that either - aliases for context such as self or that are a bit out of date, you tend to want to keep context to your instances and bind correctly

angular, ng-class with function inside repeat

I'm trying to put a class on an input if it meets certain requirements and am having problems
it looks like so -
ng-class="'isPartial': canPartial($index)"
This is inside a repeat, the function it's referring to looks like so
$scope.canPartial = function(index) {
var needsMet = _.reduce($scope.allAccounts[index].schools, function (memo, schools) {
return memo + (schools.selected ? 1 : 0);
}, 0);
console.log(needsMet);
return (needsMet === $scope.allAccounts[index].schools.length);
};
so it's using underscore.js to check if all its children are checked. I know the function works correct, however my issue is passing it as the condition for the ng-class. So if it returns true it will add the class. I'm getting a $parse.syntax error and I cannot seem to figuire out why because I se other examples of ng-class using a function. Perhaps it's because I'm trying to pass the $index, however it is inside a repeat, but I don't know if that causes an issue.
Any help would be much appreciated. Thanks!
Your ng-class expression is invalid.
Change your ng-class declaration in order to take an object as a value:
ng-class="{'isPartial': canPartial($index)}"

Categories

Resources