Conditional rendering react js - reactjs

Ok, trying to render date from one component into a second component, but using conditional rendering so if date on component 1 is null, component 2 date field will not render. New to react. using following logic.
const enpDate = (earlyNotificationDate);
if (enpDate) {
moment(earlyNotificationDate, 'MM/DD/YYYY')
}
Mentor does not like it and would rather wrap in function. Cannot get function to render properly.

You can use a ternary function condition ? value_if_true : value_if_false like so
const component = ({ isNull}) => (
<div>
{isNull ?
(
<Component1 />
) : (
<Component2 />
)}
</div>
)

Related

How to create and render components inside a Vue component like in React?

In React, you can do the following:
export const Button = ({ icon, children, ...props }) => {
const Icon = () => (
icon ? <FontAwesomeIcon icon={["fal", "check"]} className={iconPositionClass}/> : null
);
return (
<BsButton children={children} {...props}>
{iconPosition === "left"
? <><Icon/>{children}</>
: <>{children}<Icon/></>
}
</BsButton>
);
};
I can create another component inside the first one, in this case, <Icon />, and then conditionally render it inside the first one, <Button />.
With Vue, however, it's not like that, because there is no return. There's just a template tag, and while you can create a function in the <script> tag, that function cannot return html.
I know that I can re-create the above code using v-if and v-else for the actual element that I want to be rendered, but that just means that I have to repeat the code inside the <template>. It feels too repetitive.
Is there a way to re-create the React way of doing it in Vue?

How to link a text input with associated error message in a reusable React component

I have a React component called TextInput which looks like this:
const TextInput = React.forwardRef<HTMLInputElement, ITextInputProps>(
({ error, ...props }, ref) => {
return (
<>
<input
type="text"
aria-describedby="" // 👈 see here
ref={ref}
{...props}
/>
{error && (
<p> // 👈 how can I reference this?
{error}
</p>
)}
</>
)}
)
For accessibility, I am trying to link the error message to the field using aria-describedby.
In a normal HTML document I would just use the id of the paragraph tag, but with reusability in mind, I would like to learn how to do this in a React-like way.
The use of refs comes to mind, but I'm not sure how to apply it in this scenario.
I would say that the best way to do this is to create a required prop that handles the ID and you apply that ID on the aria fields.
With that in mind, if what you wanted is to generate the data dinamically you could use a useEffect running it only once and setting a state inside it.
function Component() {
const [describedBy, setDescribedBy] = useState()
useEffect(() => {
setDescribedBy(generateRandomString());
}, [])
return (
<div aria-describedby={describedBy}></div>
)
}

How to make react child component using conditional

So usually we create child component of react using code seems like this :
const component =(<button>Bla Bla</button>)
How you can create that using conditional? I have to try this one :
const component =(()=>{
if(true){
return(<button>Bla Bla</button>)
}else{
return null
}
})
but that code throw error : Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.
How to write that code properly ?
You can do that by simply passing a prop to it. Make the component like:
const Button = ({ display }) => {
return <>
{display && <button>I am Button<button>}
</>
}
Now if you want to display it you can just call it as:
<Button display={true} />
Hope this works for you.
You can do it like this
const component = true ? (<button>Bla Bla</button>): null
true can be any conditional you want to check
const myComp = ({value}) =>(
<div>
{
value &&
<myComp />
}
<div>
From my comment above. One way is to use conditional rendering in you JSX code
const bio = this.state.displayBio ? (
<div>
This is true false condition
<button onClick={this.toggleDisplay}>Show Less</button>
</div>
) : (
<div>
<button onClick={this.toggleDisplay}>Show More</button>
</div>
);

Second layer of conditional statement within inline condition react

I am trying to check the trigger status if it is new, and after that i need to check another condition and based on which i need to display tagone or tagtwo.
I have been trying to find inline documentation for this.
<modalscrolling onClose={this.props.toggleModal} open={openModal}
trigger={isNew ?
<sometag /> :
<TagOne />}>
<TagTwp />}
>
the other approach i am trying is to send it to a different function. Any suggestions to deal with this :)
you can have nested ternary operators as following,
App.js
import React from "react";
import "./styles.css";
export default function App() {
var isNew = true;
var tag = 1;
return (
<div className="App">
{isNew ? (
tag === 1 ? (
<span>tag1</span>
) : (
<span>tag2</span>
)
) : (
<span>notnew</span>
)}
</div>
);
}
demo: https://codesandbox.io/s/ecstatic-shape-r64i8
but i would suggest extract inside teranary operation to another function component which takes "tag" as input. it helps to extend your code easily and make it more readable.
App.js with another after refactoring
import React from "react";
import "./styles.css";
const AnotherCompoent = ({ tag }) => {
return tag === 1 ? <span>tag1</span> : <span>tag2</span>;
};
export default function App() {
var isNew = true;
var tag = 1;
return (
<div className="App">
{isNew ? <AnotherCompoent tag={tag} /> : <span>notnew</span>}
</div>
);
}
demo: https://codesandbox.io/s/affectionate-hertz-1ou77
You can do something like this:
<modalscrolling onClose={this.props.toggleModal} open={openModal}
trigger={isNew ? <SomeTag /> : secondLevelCondition ? <TagOne /> :<TagTwp /> }
/>
Ternary operator is better option as it helps understand the component markup. If the conditional parts are big, convert them to seperate functional components.
trigger= { isNew ? <sometag/> : { anothercond ? <TagOne /> : <TagTwo/> }}.
Is this what you're looking for?

React conditional rendering bug even with single parent and child list [duplicate]

This question already has answers here:
How can I return multiple lines JSX in another return statement in React?
(8 answers)
Closed 4 years ago.
Learning a bit of React but it seems to me like there's a conditional rendering bug with React itself.
Suppose I have a Foo component like so:
foo.js
import React, { Component } from 'react';
class Foo extends Component {
render() {
const isLoggedIn = this.props.isLoggedIn;
return(
<div>
{ isLoggedIn ? (
<div>one</div><div>two</div>
) : (
<div>one</div><div>two</div><div>three</div>
)}
</div>
);
}
}
export default Foo;
and I use it like so:
app.js
import React, { Component } from 'react';
import Foo from './components/foo';
class App extends Component {
render() {
return (
<div>
<Foo isLoggedIn={false} />
</div>
);
}
}
export default App;
This produces the error:
Syntax error: Adjacent JSX elements must be wrapped in an enclosing tag
Please note the above Foo component, there is only a single parent div being returned not array. If it was an array, then yes I agree with the error.
The official example given in the React document's example is like this:
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn ? (
<LogoutButton onClick={this.handleLogoutClick} />
) : (
<LoginButton onClick={this.handleLoginClick} />
)}
</div>
);
}
https://reactjs.org/docs/conditional-rendering.html
Does this look like a bug in React to anyone?
Update
Based on the answers and comments given here, the implied behaviour of React is ternary operators inside the render() function comes with it's own render calls behind the scenes, acting like a virtual component, which would mean an extra layer of <div> needs to be wrapped around the list of my child elements.
Emberjs Foo component
My confusion arise from the fact I have done some Emberjs development in the past and a component like this works as expected:
<h3>Foo component</h3>
{{#if isLoggedIn}}
<div>one</div><div>two</div>
{{else}}
<div>one</div><div>two</div><div>three</div>
{{/if}}
Thanks for the explanation from everyone nonetheless.
You are returning the 2 or 3 divs in the condition. Instead you should wrap them into on div and return.
Notice the wrapper div below.
{ isLoggedIn ? (
<div className='wrapper'><div>one</div><div>two</div><div>
) : (
</div className='wrapper'><div>one</div><div>two</div><div>three</div></div>
)}
Also note that there is small typo below
<div>one</div><div>two</div><div>three</div
You have a syntax error
<div>one</div><div>two</div><div>three</div
should be
<div>one</div><div>two</div><div>three</div>
Did you try adding ?
return(
<div>
{ isLoggedIn ? (
<Fragment><div>one</div><div>two</div><Fragment>
) : (
<Fragment><div>one</div><div>two</div><div>three</div><Fragment>
)}
</div>
);
Syntax error: Adjacent JSX elements must be wrapped in an enclosing tag?
you are returning multiple sibling JSX elements in an incorrect manner.
In Foo:
return(
<div>
{ isLoggedIn ? (
<div>one</div> //are siblings without
<div>two</div> //wrapping in container element.
) : (
<div>one</div> //are siblings without
<div>two</div> //wrapping in
<div>three</div>//container element.
)}
</div>
);
Right approach :
return (
<div>
{isLoggedIn
? (
<div> //add wrapper
/...
</div>
)
: (
<div> //add wrapper
//...
</div>
)}
</div>
);
Or
If you are using React16 then you can use React.Fragement as well:
e.g.
<React.Fragment>
<div>one</div>
<div>two</div>
</React.Fragment>
You need to wrap the element rendered in the condition
return(
<div>
{ isLoggedIn ? (
<div><div>one</div><div>two</div></div>
) : (
<div><div>one</div><div>two</div><div>three</div></div>
)}
</div>
);
Note the extra div around the nested conditional elements

Resources