错误React.Children.only期望接收单个React元素子级。

4
我不太确定我的应用程序出了什么问题。我正在使用create-react-app,并尝试将所有组件呈现到各自的根div中。问题是,我能够将所有组件呈现到页面上,除了最后一个分数组件。我甚至尝试将该组件投入到一个div中,但仍然遇到以下问题:“React.Children.only expected to receive a single React element child”。这是什么意思?下面是我的App.js结构:
render() {
   return (
       <div className="App">
           <div className="App-header">
              <h2>BAO BAO BAO</h2>
           </div>
           {this.state.result ? this.renderResult() : this.renderTest()}
           <Baoquestion />
           <AnswerChoices />
           <BaoScore />
           <Score />
       </div>      
    );
}


export default App;

Score.js的内容

 import React, { Component } from 'react';
 import PropTypes from 'prop-types';
 import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup';

 function Score(props) {

 return (
 <div>
 <CSSTransitionGroup 
  className="container result"
  transitionName="test"
  transitionEnterTimeout={500}
  transitionLeaveTimeout={300}>
 >
  <div>
    You prefer <strong>{props.testScore}</strong>!
  </div>
</CSSTransitionGroup>
</div>
);

 }

 Score.propTypes = {
 quizResult: PropTypes.string,
 };

 export default Score;

3
你能否更新问题,包括Score组件的render方法? - Tharaka Wijebandara
@TharakaWijebandara 刚刚编辑了!谢谢。 - Benji Durden
3个回答

7

来自react-transition-group文档

必须为CSSTransitionGroup的所有子元素提供key属性,即使只呈现一个项目也是如此。这是React确定哪些子元素已进入、离开或保持不变的方法。

因此,请为您在转换组内呈现的组件添加一个key,即使是静态的也可以:

<CSSTransitionGroup 
 className="container result"
 transitionName="test"
 transitionEnterTimeout={500}
 transitionLeaveTimeout={300}>
>
  <div key="transition-group-content" >
    You prefer <strong>{props.testScore}</strong>!
  </div>
</CSSTransitionGroup>

问题是在渲染“Score”组件时才出现的吗?我猜你已经将其注释掉了,错误会消失。如果没有,请检查其他组件和渲染函数,例如“this.renderResult()”。堆栈跟踪中是否有任何有用的信息? - Przemysław Zalewski
现在请先删除<Score>,然后重新运行测试,看看会发生什么。我认为根本问题可能出在其他地方,比如某些第三方组件只期望一个子元素,或者是在renderResultrenderTest方法中。 - Przemysław Zalewski
在移除了那个组件之后,错误不再存在。 - Benji Durden
非常奇怪...请检查更改转换组内容时是否有效:<div key="transition-group-content">测试</div>。如果您的“分数”组件与您发布的任何方式不同,请显示完整源代码。 请注意,CSSTransitionGroup用于动画化进入或离开树的动态组件,对于简单的动画,请使用纯CSS,例如animate.css<div class="animated bounce">你更喜欢<strong>{props.testScore}</strong>!</div>没有CSSTransitionGroup - Przemysław Zalewski
1
针对您的使用情况,我认为使用CSS动画是更好的方法。请注意,在Score组件中,除非您将其作为属性传递 <Score testScore={5} />,否则props.testScore未定义。 当我深入源代码时,我想到的唯一解决方案是将您的内容包装两次:<div key="transition-group-content" ><div>You prefer <strong>{props.testScore}</strong>!</div></div>,因为错误的源头在于此:return React.cloneElement(React.Children.only(this.props.children), props);,位于 https://github.com/reactjs/react-transition-group/blob/master/src/CSSTransitionGroupChild.js - Przemysław Zalewski
显示剩余7条评论

1
<CSSTransitionGroup 
 className="container result"
 transitionName="test"
 transitionEnterTimeout={500}
 transitionLeaveTimeout={300}>
>                            ^ ** Must be a typo here **
^ ** Remove this '>' typo solve my problem **

这个错误 'Error React.Children.only expected to receive a single React element child' 的根本原因是 JSX 代码结尾有两个 '>'。删除其中一个 '>' 就可以解决这个问题。

这段代码片段可能解决了问题,但它并没有说明为什么或者如何回答这个问题。请在你的代码中包含解释,因为这真的有助于提高你的帖子质量。记住,你正在回答未来读者的问题,而那些人可能不知道你的代码建议原因。 - Luca Kiebel
@LucaKiebel,感谢您的建议,我已经更新了我的帖子。 - Sonic.S.Xiang

1
我在使用CSS过渡时遇到了同样的错误。对我有效的方法是使用这些React标签:<></>将css过渡标签中的标签包装起来。
请注意,我在TransitionGroup和CSSTransition标记中有两个标记,如下所示:
 <TransitionGroup>
       <CSSTransition key={quotesArr[active]}>
          <>
            <p>{current.quote}</p>
            <h2>{current.client}</h2>
          </>
       </CSSTransition>
  </TransitionGroup>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接