Javascript 在没有包装器元素的方法中返回多个React元素

Javascript 在没有包装器元素的方法中返回多个React元素,javascript,reactjs,Javascript,Reactjs,我试图从助手方法返回多个React元素。我可以简单地通过移动一些代码来解决它,但我想知道是否有更干净的方法来解决它。我有一个方法返回render方法的一部分,函数需要返回React元素和一些文本。通过一个例子更清楚: class Foo extends React.Component { _renderAuthor() { if (!this.props.author) { return null; } return [ ' by ',

我试图从助手方法返回多个React元素。我可以简单地通过移动一些代码来解决它,但我想知道是否有更干净的方法来解决它。我有一个方法返回
render
方法的一部分,函数需要返回React元素和一些文本。通过一个例子更清楚:

class Foo extends React.Component {
  _renderAuthor() {
    if (!this.props.author) {
      return null;
    }

    return [
      ' by ',
      <a href={getAuthorUrl(this.props.author)}>{this.props.author}</a>,
    ]; // Triggers warning: Each child in an array or iterator should have a unique "key" prop.

  render() {
    return (
      <div>
        {this.props.title}
        {this._renderAuthor()}
      </div>
    );
  }
}
编辑2:


事实证明这是不可能的,我在这里写了两个变通方法:

在您的阵列上尝试这种方法:

return [
      <span key={'prefix-'+random_string_generator()}>' by '</span>,
      <a key={'prefix-'+random_string_generator()} href={getAuthorUrl(this.props.author)}>{this.props.author}</a>,
    ];
返回[
“by”,
,
];

错误消息准确地告诉您如何解决此问题:


数组或迭代器中的每个子级都应该有一个唯一的“键”属性

与此相反:

return [
  ' by ',
  <a href={getAuthorUrl(this.props.author)}>{this.props.author}</a>,
];
…无需使用
s

以下是工作片段中的前一个解决方案:

const getAuthorUrl=author=>`/${author.toLowerCase()}`;
类Foo扩展了React.Component{
_renderAuthor(){
如果(!this.props.author){
返回null;
}
返回[
通过
,
];
}
render(){
返回(
{this.props.datePosted}
{this.\u renderAuthor()}
);
}
}
ReactDOM.render(,document.getElementById('container'))

我喜欢使用If组件来处理这类事情,我将所有内容都封装到了一个span中,因为它不会真正破坏任何东西,也不会让对键的需求消失

const getAuthorUrl=author=>`/${author.toLowerCase()}`;
函数If({条件,子项}){
返回条件?React.Children.only(Children):空;
}
类Foo扩展了React.Component{
render(){
返回(
{this.props.datePosted}
通过
);
}
}
ReactDOM.render(,document.getElementById('container'))

这有点粗糙,但它没有像您希望的那样包含不必要的jsx

var author = 'Daniel';
var title = 'Hello';

var Hello = React.createClass({
  _renderAutho0r: function() {
    if (!author) {
      return null;
    }

    return <a href="#">{author}</a>
},

    render: function() {
    var by = author ? ' by ' : null;

        return (
      <div>
        {title}
        {by}
        {this._renderAutho0r()}
      </div>
    );
    }
});

React.render(<Hello name="World" />, document.body);
var作者='Daniel';
var title='Hello';
var Hello=React.createClass({
_RenderAuthor0r:函数(){
如果(!作者){
返回null;
}
返回
},
render:function(){
var by=作者?:null;
返回(
{title}
{by}
{this.\u renderAutho0r()}
);
}
});
React.render(,document.body);

我的

如果没有某种变通方法(如将所有内容包装到另一个组件中),目前不可能做到这一点,因为它最终会导致底层React代码尝试返回多个对象

不过,请查看在未来版本中考虑对其进行支持的位置


编辑:现在可以对React 16中的片段执行此操作,请参见:
还有另一种方法可以解决这个问题。我建议您创建另一个组件Author.js:

function Author(props) {
  return (<span>
    <span> by </span>
    <a href={props.getAuthorUrl(props.author)}>{props.author}</a>
  </span>)
}


class Foo extends React.Component {
  render() {
    return (
      <div>
        {this.props.title}
        {this.props.author && <Author author={this.props.author} getAuthorUrl={this.getAuthorUrl} />}
      </div>
    );
  }
}
函数作者(道具){
返回(
通过
)
}
类Foo扩展了React.Component{
render(){
返回(
{this.props.title}
{this.props.author&&}
);
}
}

但是我没有测试这段代码。但我想它看起来会更干净。希望有帮助。

至少在React 16之前,您可以从子渲染函数返回片段,但不能从主渲染函数返回片段。为此,返回一个组件数组。您不需要手动设置键,除非您的片段子项将发生更改(默认情况下,数组是使用索引设置键的)

对于创建片段,您也可以使用

对于内联使用,可以使用数组或利用立即调用的箭头函数。 请参见下面的示例:

const getAuthorUrl=author=>`/${author.toLowerCase()}`;
类Foo扩展了React.Component{
构造函数(){
超级();
this.\u renderAuthor=this.\u renderAuthor.bind(this);
this.\u renderUser=this.\u renderUser.bind(this);
}
_renderAuthor(){
如果(!this.props.author){
返回null;
}
返回[
“by”,
,
];
}
_renderUser(){
返回[
{this.props.user.name},
{this.props.user.info}

] } render(){ 返回( {this.props.datePosted} {this.\u renderAuthor()} {this.props.user ?这个。_renderUser() :找不到用户

} {this.props.user ? [ {this.props.user.name}, {this.props.user.info}

] :找不到用户

} {this.props.user ? (() => [ {this.props.user.name}, {this.props.user.info}

])() :找不到用户

} ); } } ReactDOM.render(,document.getElementById('container'))

试试这个:

class Foo extends React.Component {
    _renderAuthor() {
        return <a href={getAuthorUrl(this.props.author)}>{this.props.author}</a>
    }

    render() {
        return (
          <div>
                {this.props.title}
                {this.props.author && " by "}
                {this.props.author && this._renderAuthor()}
          </div>
        );
    }
}
类Foo扩展了React.Component{
_renderAuthor(){
返回
}
render(){
返回(
{this.props.title}
{this.props.author&&“by”}
{this.props.author&&this.\u renderAuthor()}
);
}
}

也许更简单的方法是重新思考应用程序的架构。然而,用一种更简单的方式

触发此警告是因为您试图从数组中进行渲染,而不是对元素进行反应,而是直接对html进行渲染。为了达到这个目的,你必须

{this._renderAuthor().map(
    (k,i) => (React.addons.createFragment({k}))
    )  }
React addons
createFragment
函数基本上就是这样做的,它将您的html元素减少为可以呈现的React片段

或者,在一种更好的方法中,您可以像这样创建一个AuthorLink
无状态组件

function AuthorLink(props) {
  return (
    <div className="author-link">
      <span> by </span>
      <a href={props.authorUrl}> {props.author} </a>
    </div> 
  });
}
函数AuthorLink(道具){
返回(
通过
});
}
并在主组件的渲染中使用它

render() {
  const { author } = this.props;
  return (
    <div>
      {this.props.datePosted}
      <AuthorLink url={getAuthorUrl(author)} author={author} />
    </div>
  );
}
render(){
const{author}=this.props;
返回(
{this.props
{this._renderAuthor().map(
    (k,i) => (React.addons.createFragment({k}))
    )  }
function AuthorLink(props) {
  return (
    <div className="author-link">
      <span> by </span>
      <a href={props.authorUrl}> {props.author} </a>
    </div> 
  });
}
render() {
  const { author } = this.props;
  return (
    <div>
      {this.props.datePosted}
      <AuthorLink url={getAuthorUrl(author)} author={author} />
    </div>
  );
}