[javascript] 구문 분석 오류 : 인접한 JSX 요소를 묶는 태그로 묶어야합니다.

내가 설정 React.js한 변수가 인 경우에만 렌더링되도록 앱 을 설정하려고합니다 true.

렌더링 기능 설정 방법은 다음과 같습니다.

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 (
    <div>

if(this.state.submitted==false)
{

      <input type="email" className="input_field" onChange={this._updateInputValue} ref="email" value={this.state.email} />

      <ReactCSSTransitionGroup transitionName="example" transitionAppear={true}>
      <div className="button-row">
         <a href="#" className="button" onClick={this.saveAndContinue}>Request Invite</a>
     </div>
     </ReactCSSTransitionGroup>
}
   </div>
    )
  },

기본적으로 여기서 중요한 부분은 if(this.state.submitted==false)부분입니다 ( div제출 된 변수가로 설정되면 이러한 요소가 표시 되기를 원합니다 false).

그러나 이것을 실행할 때 질문에 오류가 발생합니다.

잡히지 않는 오류 : 구문 분석 오류 : 38 행 : 인접한 JSX 요소를 묶는 태그로 묶어야합니다.

여기서 문제는 무엇입니까? 이 작업을 위해 무엇을 사용할 수 있습니까?



답변

구성 요소를 묶는 태그 사이에 두어야합니다. 즉,

// WRONG!

return (
    <Comp1 />
    <Comp2 />
)

대신 :

// Correct

return (
    <div>
       <Comp1 />
       <Comp2 />
    </div>
)

편집 : Fragments API에 대한 Per Joe Clay의 의견

// More Correct

return (
    <React.Fragment>
       <Comp1 />
       <Comp2 />
    </React.Fragment>
)

// Short syntax

return (
    <>
       <Comp1 />
       <Comp2 />
    </>
)


답변

이 질문에 대답하기는 늦었지만 설명에 추가 할 것이라고 생각했습니다.

코드의 어느 위치에서나 두 요소를 동시에 반환하기 때문에 발생합니다.

예 :

return(
    <div id="div1"></div>
    <div id="div1"></div>
  )

부모 요소 로 싸야 합니다. 예 :

 return(
      <div id="parent">
        <div id="div1"></div>
        <div id="div1"></div>
      </div>
      )


더 자세한 설명

아래 jsx코드가 변형됩니다

class App extends React.Component {
  render(){
    return (
      <div>
        <h1>Welcome to React</h1>
      </div>
    );
  }
}

이것으로

_createClass(App, [{
    key: 'render',
    value: function render() {
      return React.createElement(
        'div',
        null,
        React.createElement(
          'h1',
          null,
          'Welcome to React'
        )
      );
    }
  }]);

하지만 이렇게하면

class App extends React.Component {
  render(){
    return (
        <h1>Welcome to React</h1>
        <div>Hi</div>
    );
  }
}

이것은 이것으로 변환됩니다 (일러스트 목적으로 실제로, 당신은 얻을 것입니다 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'
        )
    }
  }]);

위의 코드 에서 메소드 호출에서 두 번 리턴하려고 시도하고 있음을 알 수 있습니다 .

React 16 및 최신 버전의 최신 변경 사항 :

랩을 위해 여분의 div를 추가하고 싶지 않고 둘 이상의 하위 구성 요소를 반환하려는 경우 사용할 수 있습니다 React.Fragments.

React.Fragments 약간 더 빠르며 메모리 사용량이 적습니다 (추가 DOM 노드를 만들 필요가 없으며 덜 복잡한 DOM 트리가 필요 없음).

(React 16.2.0에서)

render() {
  return (
    <>
       React fragments.
      <h2>A heading</h2>
      More React fragments.
      <h2>Another heading</h2>
      Even more React fragments.
    </>
  );
}

또는

render() {
  return (
    <React.Fragments>
       React fragments.
      <h2>A heading</h2>
      More React fragments.
      <h2>Another heading</h2>
      Even more React fragments.
    <React.Fragments/>
  );
}

또는

render() {
 return [
  "Some text.",
  <h2 key="heading-1">A heading</h2>,
  "More text.",
  <h2 key="heading-2">Another heading</h2>,
  "Even more text."
 ];
}


답변

리 액트 요소는 하나의 요소 만 반환해야합니다. 두 요소를 다른 요소 태그로 감싸 야합니다.

또한 렌더링 함수가 아무것도 반환하지 않는 것을 볼 수 있습니다. 구성 요소는 다음과 같습니다.

var app = React.createClass({
    render () {
        /*React element can only return one element*/
        return (
             <div></div>
        )
    }
})

또한 if반환 된 요소 내 에서는 문을 사용할 수 없습니다 .

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 <YourJSX />
    } else {
        return <YourOtherJSX />
    }
},


답변

다른 답변에서 제안한 것처럼 다른 div에 래핑하지 않으려면 배열로 래핑하면 작동합니다.

// Wrong!
return (
   <Comp1 />
   <Comp2 />
)

다음과 같이 쓸 수 있습니다.

// Correct!
return (
    [<Comp1 />,
    <Comp2 />]
)

위의 내용은 경고를 생성합니다. Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of 'YourComponent'.

key수동으로 추가하면 다음과 같이 속성을 구성 요소 에 추가하여 문제를 해결할 수 있습니다 .

return (
    [<Comp1 key="0" />,
    <Comp2 key="1" />]
)

키에 대한 추가 정보는 다음과 같습니다. 컴포지션 vs 상속


답변

문제

구문 분석 오류 : 인접한 JSX 요소를 묶는 태그로 묶어야합니다.

이는 여러 형제 JSX 요소를 잘못된 방식으로 반환하려고 함을 의미합니다. HTML을 작성하는 것이 아니라 JSX를 작성한다는 것을 기억하십시오! 코드가 JSX에서 JavaScript로 변환되었습니다. 예를 들면 다음과 같습니다.

render() {
  return (<p>foo bar</p>);
}

다음으로 번역됩니다 :

render() {
  return React.createElement("p", null, "foo bar");
}

일반적으로 프로그래밍에 익숙하지 않은 한, 함수 / 메소드 (모든 언어)는 여러 매개 변수를 사용하지만 항상 하나의 값만 반환한다는 것을 이미 알고 있습니다 . 이를 감안할 때 createElement()작동 방식에 따라 여러 형제 구성 요소를 반환하려고 할 때 문제가 발생했음을 알 수 있습니다 . 하나의 요소에 대해서만 매개 변수를 취하여이를 리턴합니다. 따라서 하나의 함수 호출에서 여러 요소를 반환 할 수 없습니다.


왜 이것이 효과가 있는지 궁금하다면 …

render() {
  return (
    <div>
      <p>foo</p>
      <p>bar</p>
      <p>baz</p>
    </div>
  );
}

그러나 이것은 …

render() {
  return (
    <p>foo</p>
    <p>bar</p>
    <p>baz</p>
  );
}

첫 번째 코드에서 두 때문이다 <p>-elements 중 일부 children<div>– 요소. 그것들이 일부일 때 children우리는 무제한의 형제 요소를 표현할 수 있습니다. 이것이 어떻게 변환되는지 살펴보십시오.

render() {
  return React.createElement(
    "div",
    null,
    React.createElement("p", null, "foo"),
    React.createElement("p", null, "bar"),
    React.createElement("p", null, "baz"),
  );
}

솔루션

실행중인 React 버전에 따라이를 해결하기위한 몇 가지 옵션이 있습니다.

  • 조각 사용 (React v16.2 + 만 해당)

    React v16.2부터 React는 자식을 직접 반환하는 노드가없는 구성 요소 인 Fragments 를 지원합니다 .

    배열에서 자식을 반환하면 (아래 참조) 몇 가지 단점이 있습니다.

    • 배열의 자식은 쉼표로 구분해야합니다.
    • 배열의 자식에는 React의 키 경고를 방지하기위한 키가 있어야합니다.
    • 문자열은 따옴표로 묶어야합니다.

    이들은 프래그먼트를 사용하여 제거됩니다. 다음은 조각으로 싸인 아이들의 예입니다.

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

    어떤 설탕을 제거 하는가?

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

    첫 번째 스 니펫에는 Babel v7.0 이상이 필요합니다.


  • 배열 반환 (React v16.0 + 만 해당)

    React v16부터 React Components는 배열을 반환 할 수 있습니다. 이것은 모든 형제 컴포넌트를 상위 컴포넌트에 랩핑해야하는 이전 버전의 React와 다릅니다.

    즉, 이제 다음을 수행 할 수 있습니다.

    render() {
      return [<p key={0}>foo</p>, <p key={1}>bar</p>];
    }

    이것은 다음으로 번역됩니다.

    return [React.createElement("p", {key: 0}, "foo"), React.createElement("p", {key: 1}, "bar")];

    위의 배열을 반환합니다. 배열은 React 버전 16 이상부터 유효한 React 요소입니다. 이전 버전의 React의 경우 배열은 유효한 반환 객체가 아닙니다!

    또한 다음은 유효하지 않습니다 (배열을 반환해야 함).

    render() {
      return (<p>foo</p> <p>bar</p>);
    }

  • 부모 요소로 요소 감싸기

    다른 솔루션에는 형제 구성 요소를 포함하는 상위 구성 요소를 만드는 것이 포함됩니다 children. 이것은이 문제를 해결하는 가장 일반적인 방법이며 모든 버전의 React에서 작동합니다.

    render() {
      return (
        <div>
          <h1>foo</h1>
          <h2>bar</h2>
        </div>
      );
    }

    참고 : 자세한 내용과이 변환 방법에 대해서는이 답변 상단을 다시 살펴보십시오 .


답변

React 16.0.0 렌더에서 여러 컴포넌트를 배열로 반환 할 수 있습니다.

return ([
    <Comp1 />,
    <Comp2 />
]);

React 16.4.0 에서는 Fragment 태그의 여러 컴포넌트를 렌더링에서 반환 할 수 있습니다. 파편

return (
<React.Fragment>
    <Comp1 />
    <Comp2 />
</React.Fragment>);

향후 React 에서는이 속기 구문을 사용할 수 있습니다. (많은 툴은 아직 지원하지 않으므로 <Fragment>툴링이 잡힐 때까지 명시 적으로 작성 하는 것이 좋습니다.)

return (
<>
    <Comp1 />
    <Comp2 />
</>)


답변

구성 요소를 포장하지 않으면 아래 언급 된 방법으로 작성할 수 있습니다.

대신에:

return(
  <Comp1 />
  <Comp2 />
     );

당신은 이것을 쓸 수 있습니다 :

return[(
 <Comp1 />
),
(
<Comp2 />
) ];