below is a inline if with logical && operator that renders a component if this.state.isHidden is false.
<div>{!this.state.isHidden && <ShowThisComponent /> }</div>
The above line works as expected. My problem is that I cannot figure out how to add a second condition to be met (e.g var1 === var2) to the above line. So that if both return true, the component gets displayed. How can I do this? thanks
I've looked at the documentation (https://reactjs.org/docs/conditional-rendering.html#inline-if-with-logical-ampamp-operator) could not find an answer
This is how the operator works:
{<any boolean statement> && <Component-to-be-displayed />}.
-or-
{(<any boolean statement>) && <Component-to-be-displayed />} ... it's always a good idea to use parentheses when analysing boolean statements
In your case it would look something like this :
(!this.state.isHidden && var1 === var2) && <Component-to-be-displayed />
so think of the operator like this:
if condition is true && render component
You can also perform an if-statement:
{(<any boolean statement>) ?
<Component-to-be-displayed-if-true />
:
<Component-to-be-displayed-if-false />
}
you can think of this operator like this:
if condition is true ? render component A : else render component B
{ (!this.state.isHidden && var1 === var2) && <ShowThisComponent /> }
{ !this.state.isHidden && secondCondition && <ShowThisComponent /> }
Related
I have 3 variables that I must evaluate to hide a div if a condition is met between these 3 variables, something like this:
appState.fullResults
appState.someResults
appState.otherResults
So, when appState.fullResults and appState.someResults come empty, but appState.otherResults has something, I need to hide a div, this code snippet is an example:
<div classname='container'>
<div classname='full-some'>
boxes
</div>
<divclassname='others'>
boxes
</div>
</div>
I try something like this, but dont work
className={`${
(!appState.someResults?.length > 0 && otherResults?.length > 0)
? 'container-boxcard'
: 'd-none'
}`}
I always get the same result: if othersResults brings something and someResults brings nothing, the "d-none" is not passed to hide it
https://imgur.com/bZBUGo9
Still evaluates false and applies the d-none class
Hope I have explained well, thank you for your help.
Try this :
const { fullResults, someResults, otherResults } = appState;
const className = !fullResults?.length && !someResults?.length
&& otherResults?.length ? 'd-none' : 'container-boxcard';
<YourComponent className={className} {...props} />
!appState.someResults?.length > 0 is hard to understand, I'd suggest you should change it to !appState.someResults?.length or appState.someResults?.length === 0 (you can choose one of them).
I haven't seen you declared otherResults anywhere else, so I'd assume that otherResults?.length > 0 should be appState.otherResults?.length (or appState.otherResults?.length > 0).
className={`${(!appState.someResults?.length && appState.otherResults?.length)
? 'd-none'
: 'container-boxcard'
}`}
when appState.fullResults and appState.someResults come empty, but appState.otherResults has something
According to your demonstration, you can follow this with 3 conditions
className={`${(!appState.someResults?.length && !appState.fullResults?.length && appState.otherResults?.length)
? 'd-none'
: 'container-boxcard'
}`}
finally it was a problem with the function that created the objects fullResults, someResults & otherResults, it was passing all the answer to the object, creating another object inside, that's why always the object even if it had no data inside, evaluated length greater than 0 because it had something inside,
setAppQuotationState({
loading: false,
fullResults: fullResults?.length > 0 ? [fullResults] : [],
someResults: someResults?.length > 0 ? [someResults] : [],
otherResults: otherResults?.length > 0 ? [otherResults] : [],
})
}
correcting that bug, the solutions that I indicated, worked well.
state = {
count: 1,
};
render() {
let classes = "badge m-5 bg-";
let { count } = this.state;
count === 1 ? (classes += "success") : (classes += "warning");//1st Condition
classes+= (count===1)?"success" : "warning";//2nd Condition
return (
<div className="container">
<span style={this.styles} className={classes} id="bad">
Hello!
</span>
</div>
);
}
I understood how that if condition works(condition ? true: false), but in the 2nd condition how it is possibly working even after placing the classes+= even before mentioning the condition?
Let's break it down. Remember, our initial value of count is 1.
let classes = "badge m-5 bg-";
...
classes+= (count===1)?"success" : "warning";
Firstly what'll happen is that count===1 will be checked for strict equality (it takes precedence), which will yield true. Since our condition is true, and we're using ternary operator, the expression returns "success" string, i.e.,
this:
classes+= (count===1)?"success" : "warning";
becomes this:
classes+= "success";
"success" will be appended to the classes string, therefore classes will become badge m-5 bg-success
In 2nd Condition, tt related to javascript operator precedence. ?: before +=
In Javascript, ternary operator (?...:) takes precedence over assignment (+=), so the right hand of the += resolves first and append either "success" or "warning" to classes.
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table
GOAL: Don't show Navigation component when the pathname includes either /create-page or add-block
Currently, the Navigation shows on both pages
<Route
path={[
"/affiliate-code",
"/dashboard",
"/editor",
"/locked",
"/saved",
"/notifications",
"/:id",
"/",
]}
component={() =>
window.location.pathname != ("/create-page" || "/add-block") && (
<Navigation
key={window.location.pathname}
newNotification={newNotification}
/>
)
}
/>
You cannot use an OR operator like so, you need to compare each value in the eval statement. If you want 1 statement I would suggest something like this:
!["/create-page","/add-block"].includes(window.location.pathname) && (
...
)
Change window.location.pathname != ("/create-page" || "/add-block")
to
window.location.pathname != "/create-page" && window.location.pathname != "/add-block"
The first one will always end up to be window.location.path != "/create-page" because string is a truthy value. But still the case of /create-page should have passed. Maybe the string isn't exact so you can use .includes for the purpose.
i want to render the jsx based on a condition using ternary operation in react.
What i am trying to do?
i have the code like below that works perfect.
return (
{this.has_rendered() && this.items_loaded()
? <ChildComponent/>
: <ChildComponent
on_prev={null}/>}
)
Now i want to check for other condition if its !current_user then i want to pass another prop named "on_next" to ChildComponent.
{this.has_rendered() && this.items_loaded() && !current_user &&
<ChildComponent/>}
{!this.has_rendered() && !this.items_loaded() && !current_user &&
<ChildComponent on_prev={null}/>}
{this.has_rendered() && this.itemss_loaded() && current_user &&
<ChildComponent
on_next={somevalue}/>}
{!this.has_rendered() && !this.items_loaded() && current_user &&
<NavigationContent
on_prev={null}
on_next={somevalue}/>}
The above code works but as you see there is repetition of code. how can i fix this with ternary operator. could someone help me with this.
thanks.
Nested ternary is a bad idea.
You should use variables in this case
let component = null;
if (this.has_rendered() && this.items_loaded()) {
component = current_user? <ChildComponent/> : <ChildComponent on_prev={null}/>
} else {
component = ...
}
If on_prev and on_next attributes can have values all the time, consider this approch:
return (
{ this.has_rendered() &&
<ChildComponent
on_prev={this.items_loaded() ? somevalue : null }
on_next={current_user ? someanothervalue : null} />
}
)
I've been struggeling with this basic stuff for a while now, but I cant seem to get it to work.
I'm getting data from our backend and if there're any deliveries objects it will be displayed with this:
<Expandable>
<ObjectDisplay
key={id}
parentDocumentId={id}
schema={schema[this.props.schema.collectionName]}
value={this.props.collection.documents[id]}
/>
</Expandable>
But if there is no deliveries I'd like to display a message like there's no deliveries. I can use .length and !deliveries (I get that), but it seems like my conditional isn't working:
render() {
console.log(this.props.collection.ids.length) //Getting how many deliveries there are with their id
return (
<div>//Struggling with this:
{!this.props.collection.ids && this.props.collection.ids.length < 1
? <p>No deliviers</p>
: <div className="box">
{this.props.collection.ids
.filter(
id =>
// note: this is only passed when in top level of document
this.props.collection.documents[id][
this.props.schema.foreignKey
] === this.props.parentDocumentId
)
.map(id => {
return (
<Expandable>
<ObjectDisplay
key={id}
parentDocumentId={id}
schema={schema[this.props.schema.collectionName]}
value={this.props.collection.documents[id]}
/>
</Expandable>
)
})}
</div>}
</div>
)
}
I bet my problem is super basic, but I just can't get it to work.. Help is much appreciated!!
Change your && to ||. You want to render "no delivers" if you have no ids (first test) OR if your ids.length is < 1
Your problem seems indeed to be with your condition.
!this.props.collection.ids && this.props.collection.ids.length < 1
!this.props.collection.ids is only true when the array is falsy. However, an empty array is not falsy - it's truthy.
this.props.collection.ids.length < 1 is true when the array is empty.
Since you are doing && you require the array to be falsy and empty at the same time, which can never happen.
So simply change the condition from && to || and it should work. In other words:
!this.props.collection.ids || this.props.collection.ids.length < 1
though I think this is prettier:
!this.props.collection.ids || !this.props.collection.ids.length
Your condition throws an error. See here
!this.props.collection.ids && this.props.collection.ids.length < 1
^
!false && undefined
Change your condition to
this.props.collection.ids && this.props.collection.ids.length > 1
and put your placeholder in the else block of your ternary.