可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am trying to set up my React.js app so that it only renders if a variable I have set is true.
The way my render function is set up looks like:
render: function() { var text = this.state.submitted ? 'Thank you! Expect a follow up at '+email+' soon!' : 'Enter your email to request early access:'; var style = this.state.submitted ? {"backgroundColor": "rgba(26, 188, 156, 0.4)"} : {}; return ( ) },
Basically, the important portion here is the if(this.state.submitted==false) portion (I want these divs to show up when the submitted variable is set to false).
But when running this, I get the error in the Question:
Uncaught Error: Parse Error: Line 38: Adjacent JSX elements must be wrapped in an enclosing tag
What is the issue here? And what can I use to make this work?
回答1:
You should put your component between an enclosing tag, Which mean:
//WRONG! return ( )
Instead:
//Correct return (
)
回答2:
It is late to answer this question but I thought It will add to the explanation.
It is happening because any where in your code you are returning two elements simultaneously.
e.g
return( )
It should be wrapped in a parent element. e.g
return( )
More Detailed Explanation
Your below jsx
code get transformed
class App extends React.Component { render(){ return (
Welcome to React
); } }
into this
_createClass(App, [{ key: 'render', value: function render() { return React.createElement( 'div', null, React.createElement( 'h1', null, 'Welcome to React' ) ); } }]);
But if you do this
class App extends React.Component { render(){ return ( Welcome to React
Hi ); } }
this gets converted into this(Just for illustration purpose,actually you will get error : Adjacent JSX elements must be wrapped in an enclosing tag
)
_createClass(App, [{ key: 'render', value: function render() { return React.createElement( 'div', null, 'Hi' ); return React.createElement( 'h1', null, 'Welcome to React' ) } }]);
In the above code you can see that you are trying to return twice from a method call, which is obviously wrong.
回答3:
React element has to return only one element. You'll have to wrap both of your tags with another element tag.
I can also see that your render function is not returning anything. This is how your component should look like:
var app = React.createClass({ render () { /*React element can only return one element*/ return ( ) } })
Also please note that you can't use if statments inside of a retuned element.
render: function() { var text = this.state.submitted ? 'Thank you! Expect a follow up at '+email+' soon!' : 'Enter your email to request early access:'; var style = this.state.submitted ? {"backgroundColor": "rgba(26, 188, 156, 0.4)"} : {}; if(this.state.submitted==false) { return } else { return } },
回答4:
If you don't want to wrap it in another div as other answers have suggested, you can also wrap it in an array and it will work.
// Wrong! return ( )
It can be written as:
// Correct! return ( [, ] )
Please note that the above will generate a warning: Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of 'YourComponent'.
This can be fixed by adding a key
attribute to the components, if manually adding these add it like:
return ( [, ] )
Here is some more information on keys: http://facebook.github.io/react/docs/multiple-components.html#dynamic-children
回答5:
The problem
Parse Error: Adjacent JSX elements must be wrapped in an enclosing tag
This means that you are trying to return multiple sibling JSX elements in an incorrect manner. Remember that you are not writing HTML, but JSX! Your code is transpiled from JSX into JavaScript. For example:
render() { return (foo bar
); }
will be transpiled into:
render() { return React.createElement("p", null, "foo bar"); }
Unless you are new to programming in general, you already know that functions/methods (of any language) take any number of parameters but always only return one value. Given that, you can probably see that a problem arises when trying to return multiple sibling components based on how createElement()
works; it only takes parameters for one element and returns that. Hence we cannot return multiple elements from one function call.
So if you've ever wondered why this works...
render() { return ( ); }
but not this...
render() { return ( foo
bar
baz
); }
it's because in the first snippet, both
-elements are part of children
of the -element. When they are part of
children
then we can express an unlimited number of sibling elements. Take a look how this would transpile:
render() { return React.createElement( "div", null, React.createElement("p", null, "foo"), React.createElement("p", null, "bar"), React.createElement("p", null, "baz"), ); }
Solutions
Depending on which version of React you are running, you do have a few options to address this:
Use fragments (React v16.2+ only!)
As of React v16.2, React has support for Fragments which is a node-less component that returns its children directly.
Returning the children in an array (see below) has some drawbacks:
- Children in an array must be separated by commas.
- Children in an array must have a key to prevent React’s key warning.
- Strings must be wrapped in quotes.
These are eliminated from the use of fragments. Here's an example of children wrapped in a fragment:
render() { return ( > ); }
which de-sugars into:
render() { return ( ); }
Note that the first snippet requires Babel v7.0 or above.
Return an array (React v16.0+ only!)
As of React v16, React Components can return arrays. This is unlike earlier versions of React where you were forced to wrap all sibling components in a parent component.
In other words, you can now do:
render() { return [foo
, bar
]; }
this transpiles into:
return [React.createElement("p", {key: 0}, "foo"), React.createElement("p", {key: 1}, "bar")];
Note that the above returns an array. Arrays are valid React Elements since React version 16 and later. For earlier versions of React, arrays are not valid return objects!
Also note that the following is invalid (you must return an array):
render() { return (foo
bar
); }
Wrap the elements in a parent element
The other solution involves creating a parent component which wraps the sibling components in its children
. This is by far the most common way to address this issue, and works in all versions of React.
render() { return (
foo
bar
); }
Note: Take a look again at the top of this answer for more details and how this transpiles.
回答6:
As per React 16 we can return multiple components from render as an array.
(with NO parent div
) it will render the component as one big object.
return ([ , ]);
回答7:
Import view and wrap in View
. Wrapping in a div
did not work for me.
import { View } from 'react-native'; ... render() { return ( foo
bar
); }