How to Return Multiple Lines Jsx in Another Return Statement in React

How can I return multiple lines JSX in another return statement in React?

Try to think of the tags as function calls (see the documentation). Then the first one becomes:

{[1,2,3].map(function (n) {
return React.DOM.p(...);
})}

And the second one:

{[1,2,3].map(function (n) {
return (
React.DOM.h3(...)
React.DOM.p(...)
)
})}

It should now be clear that the second snippet doesn't really make sense (you can't return more than one value in JavaScript). You have to either wrap it in another element (most likely what you'd want, that way you can also provide a valid key property), or you can use something like this:

{[1,2,3].map(function (n) {
return ([
React.DOM.h3(...),
React.DOM.p(...)
]);
})}

With JSX syntactic sugar:

{[1,2,3].map(function (n) {
return ([
<h3></h3>, // note the comma
<p></p>
]);
})}

You don't need to flatten the resulting array. React will do that for you. See the following fiddle http://jsfiddle.net/mEB2V/1/. Again: Wrapping the two elements into a div/section will most likely be better long term.

Returning multiple elements in JSX

If you are using React v16.2.0 and above you can use the shorter version of Fragments

<>
<NavItem onClick={this.login}>Zaloguj się</NavItem>
<NavItem onClick={this.login}>Zaloguj się</NavItem>
</>

If you are using a version below React v16 you can only return one element in jsx, so you have to wrap your elements inside one:

<div>
<NavItem onClick={this.login}>Zaloguj się</NavItem>
<NavItem onClick={this.login}>Zaloguj się</NavItem>
</div>

If you are using React v16 and abose you can use Fragments

import React, { Fragment } from 'react';

...
...

<Fragment>
<NavItem onClick={this.login}>Zaloguj się</NavItem>
<NavItem onClick={this.login}>Zaloguj się</NavItem>
<Fragment/>

You could also return an Array of Elements as announced here:

 return [
<NavItem key="1" onClick={this.login}>Zaloguj się</NavItem>,
<NavItem key="2" onClick={this.login}>Zaloguj się</NavItem>
];

Depending on your environment you might not be able to use all of these solutions: support for fragments

Return multiple elements inside React.render()

In React < v16.0 the render method can only render a single root node. (update: this is changed in v16, see below). In your case, you're returning 3 nodes. To get around this you can wrap your 3 nodes in a single root node:

render: function(){
return (
<div>
<h3>Account</h3>
<a href="#" onClick={some_event}>Login</a>
<a href="#" onClick={some_event}>Logout</a>
</div>
)}

In React v16 it's possible for render() to return an array of elements.

Like with other arrays, you’ll need to add a key to each element to avoid the key warning:

render() {
return [
<ChildA key="key1" />,
<ChildB key="key2" />,
<ChildC key="key3" />,
];
}

Another option is to use a Fragment. Fragments let you group a list of children without adding extra nodes to the DOM.

render() {
return (
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
);
}

There is also a short syntax (<>) for declaring fragments:

render() {
return (
<>
<ChildA />
<ChildB />
<ChildC />
</>
);
}

Can I do a switch statement inside a return statement in react

Yes, sort-of.

In React, functions that return Components must always return a single object: so if you want to return multiple Component objects (incl JSX) then you need to either wrap them in another outer Component - or return a JS array of components.

So that means if you want to return "Component1-and-Component2 OR Component1-and-Component3" then you should return an array, as either...:

[ <Component1/>, <Component2/> ] ...or [ <Component1/>, <Component3/> ]

...while the switch block in JavaScript itself is a statement and not an expression, JavaScript already has an expression equivalent: the ternary operator ?:, it's just slightly messier to deal with.

...but that means you can return a JS array literal with Component2 or Component3 as the last element, chosen with the ?: operator, like so:

const Component = () => {
let x = 1

return [
// Element 0:
<Component1 />,
// Element 1:
( x === 1 ) ? <Component2 /> :
( x === 2 ) ? <Component3 /> :
throw new Error( "This should never happen." )
];
}

Though if you know that x will always only ever be 1 or 2 then (in addition to using a custom type for x instead of number) then you can do just this:

const Component = () => {
let x = 1

return [
<Component1 />,
( x === 1 ) ? <Component2 /> : <Component3 />
];
}

Multi-line JavaScript inside JSX?

If you want to do multi-line JavaScript code, you can wrap your JS code with an IIFE, for example:

  <>
{(() => {
const a = [1, 2, 3].find((el) => el === 2)
// as much code as you want ...
// ...
// ...
console.log(a)
})()}
</>

Just in case you don't know, <> & </> are called React fragments, you can use any valid JSX element you want, for example, you can use instead <div>, <b>, <p> or anything like that.

Why return multiple elements in React is not allowed?

React implementation relies on constructing a tree like structure which it uses to for reconcilation. When you return multiple elements from React elements from the render method, the assumtion that the tree will have one root node for the Component will not longer hold, hence making it difficult to process reconcilation algorithm.

Thus react gives you a limitation to provide a root node. If you return an array of elements from v16 onwards, react will internally create a dummy node as the parent.

From version 16.2 onwards React provides a React.Fragment component, that provides a cleaner syntax to return multiple elements

render(){
return(
<React.Fragment>
<div />
<div />
</React.Fragment>
)
}

Return multiple React elements in a method without a wrapper element

It's not currently possible to do this without some sort of workaround like wrapping everything in another component, since it ends up with the underlying React code trying to return multiple objects.

See this active Github issue where support for this is being considered for a future version though.


Edit: You can now do this with Fragments in React 16, see:
https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html

Conditional in jsx return statement

Try this :

return values.map(value => {
const Tag = `h${head ? 'th' : 'td'}`;
return <Tag key={uuidv4()}>{value}</Tag>
});


Related Topics



Leave a reply



Submit