refactor react code to check state null condition - reactjs

I have working react-native code as sample below, I plan to refactor for readable reason, basically I need to check if state.room has content then return Text with then content of field
return (
{ state.room ?
<Text>{state.room.name}</Text>
: null }
{ state.room ?
<Text>{state.room.address}</Text>
: null }
);

You can use { state.room && <Text>{state.room.name}</Text> } instead.

You can simply check that state.room is truthy before you are trying to touch it once before the return statement and then assume it is fine.
if (!state.room) {
return null;
}
return (
<React.Fragment>
<Text>{state.room}</Text>
<Text>{state.room.address}</Text>
</React.Fragment>
)

You can just simply check write as
return state.room && (
<>
<Text>{state.room.name}</Text>
<Text>{state.room.address}</Text>
</>
)
If fragment shorthand is not supported, you can write as React.Fragment instead of <>.
It will return only render the markup if state.room is not falsy.

Related

Cannot convert undefined or null to object in React JS

I have a problem about implementing conditional rending in return part of functional component.
I got this kind of error shown below.
Cannot convert undefined or null to object
While some links have more than one link, others have only one link.
How can I fix my issue?
Here is my code shown below.
{Object.keys(projectDialog?.links).length > 1 ? (
projectDialog?.links
.map((link, index) => (
{link.icon}
))
) : (
{projectDialog?.links.icon}
)
}
You need additional check for cases if projectDialog or projectDialog?.links are null or undefined, for better readability and prevent from nested ternary conditional rendering I would write in such way:
...
if (!projectDialog || !projectDialog?.links) return null;
//after above check you can be sure that below return will be with defined values
return (
{Object.keys(projectDialog?.links).length > 1 ? (
projectDialog?.links.map((link, index) => (
{link.icon}
))
) : (
{projectDialog?.links.icon}
)
}
)

React return html based on condition

I have following code
function BookMaster()
{
const [BookDetails,setBookDetails] = useState({})
useEffect(()=> {
-----here API call
setBookDetails(res.data)
Here, BookDetails has a flag "IsAllowed"
And I want to return the HTML based on this Flag, something like follows
return (
if({BookDetails.IsAllowed==1})
{
<div><Label>This book is allowed</Label>
}
else
{
<div><Label>This book is NOT allowed</Label>
}
)
But this is not working as expected. Could you please share your thoughts?
First of all:
if({BookDetails.IsAllowed==1}) this code is wrong, it should be
if( BookDetails.IsAllowed==1 )
does it fix it?
In the if condition parenthesis are not allowed. Basically its a syntax error. try the below one
return (
<div>
<Label>
{ BookDetails.IsAllowed === 1
? 'This book is allowed'
: 'This book is NOT allowed' }
</Label>
</div>
)
if you are not using locale and interested to add template literals, try below one
return (
<div>
<Label>
{`This book is ${BookDetails.IsAllowed !== 1 ? 'NOT' : '' } allowed`}
</Label>
</div>
)

How to use ternary operator for returning jsx using react and typescript?

i want to return jsx based on condition using ternary operator.
what i am trying to do?
If admin variable is
true then display text "hello i am admin"
false then display text "hello i am normal user"
i have the below code to do so
function Text({is_admin}: Props) {
return is_admin ? (
<span>Hello i am admin</span>) : (
<span>Hello i am normal user </span>)
);
}
this code works. now i want to add another condition
if is_admin is true and has count < 0 display text "not visible user" and do not display text "hello i am admin"
and text "hello i am normal user" will be displayed if is_admin is false
how can i modify the above code to fit these conditions. could someone help me with this? thanks.
Instead of having deeply nested ternary operations, you can simplify the component by utilising early returns.
This will reduce the need to implement nested if..else/ternary operator statements. In addition, it is much more readable.
// not admin
if (!is_admin) {
return <span>Hello i am normal user </span>;
}
// admin, count < 0
if (count < 0) {
return <span>not visible user</span>;
}
// admin, count > 0
if (count > 0) {
return <span>Hello i am admin</span>;
}
You can chain those ternary operations ad infinitum.
function Text({ is_admin }: Props) {
const count = ...;
return is_admin
? count < 0
? (<span>Not visible user</span>)
: (<span>Hello i am admin</span>)
: (<span>Hello i am normal user </span>));
}
This is something to think about to avoid due to readability, though.
Hope it helps.
You could nest ternary condition, but this is not recommended because it's considered tough to read.
I would recommend something like this
function Text({is_admin, count}: Props) {
if (is_admin) {
return count < 0 ? <span>not visible user</span> : <span>Hello i am admin</span>
}
return <span>Hello i am normal user </span>
}

How to render jsx based on some condition using ternary operation in react?

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

Is there a better way to use conditionals inside jsx?

I've been learning React for the past few weeks and one thing that I don't like is that I have to use ternary operator for if else inside the render function.
Something like:
function render() {
return (
{x==="Let's go" ? <Go /> : <Hold on />}
)
}
Is there a way I can use a traditional if-else or switch for that matter with jsx syntax in React?
I utilize a few approaches to clean up the render method of more complex components.
1) Use a variable. Before you are actually in the JSX portion (the return) you can use the flexibility of raw JS to build variables. To take your example...
function render() {
let body;
if (x === "Let's go") {
body = <Go />
} else {
body = <Hold on />;
}
return (
<div>
{body}
</div>
);
}
Note that the top level needs to be wrapped, just put an extra div in there.
2) Use a function. This example is probably a little too simplistic but you'll get the idea..
renderBody() {
let body;
if (x === "Let's go") {
body = <Go />
} else {
body = <Hold on />;
}
return (
{body}
)
}
render() {
return (
<div>
{renderBody()}
</div>
)
}
3) Use an array (really a subset of #1) but oftentimes I find scenarios where sometimes I need to return 1 element but other times I need to return a variable number of elements. I will create an array at the top of the function and then push/unshift elements onto the array. Note that any time that you are building an array you must provide a key for each element so that React can update it properly.
let els = [
<div key="always">Always here</div>
];
if (foo) {
els.push(<div key="ifFoo">Conditionally Here</div>)
}
And then you just use the {els} variable in your main JSX.
4) Return null when you don't want anything to render
I prefer this syntax
function render() {
if (x==="Let's go") return <Go />;
return <Hold on />;
}

Resources