为什么我不能在React组件中独立于.map使用.sort?

时间:2019-02-16 15:30:52

标签: javascript reactjs

我需要按特定属性对对象数组进行排序,并以正确的顺序为每个对象渲染一个<Entry />组件。麻烦的是,我需要在第一个<Entry />之后直接放置一个单独的组件。因此,我需要按以下顺序进行操作:1-对数组进行排序。 2-渲染第一个<Entry />,然后渲染一次性组件。 3-映射其余排序的数组,并渲染其余<Entry />个。

但是React不允许我独立于.sort使用.map

这就是我想要做的:

render() {
return (
    <React.Fragment> 
        {entries.sort((a, b) => b.likes - a.likes)}

        <Entry entryNumber={entries[0].id} />

        <OneOffComponent />

        {entries.map((entry, index) => {
          if (index > 0) {
            return <Entry entryNumber={entry.id} />
          }
        }}
    </React.Fragment> 
);
}

但是这段代码给了我一个错误:“未捕获的错误:对象作为React子对象无效(找到:带有键{entryId,text,likes,user,date}的对象)。如果要渲染的集合孩子,请改用数组。”

3 个答案:

答案 0 :(得分:0)

与您的代码有关的一些事情:

  • 应在返回ReactElement之前执行变量分配。

  • 应在render函数(而不是数组)中返回ReactElement。 这可能是一个React.Fragment,一个HTML元素或一个包含零个或多个React元素的React组件。

您可以对数组进行解压以在排序后的其余项中挑选出条目。

render() {
  // say you have entries array from props, state or where ever  ¯_(ツ)_/¯
  entries.sort((a, b) => b.likes - a.likes)
  const [firstEntry, ...rest] = entries;
  const restEntries = rest.map(
     entry => <Entry key={entry.id} entryNumber={entry.id} />
  );

  return (
    <React.Fragment> 
      <Entry entryNumber={firstEntry.id} />
      <OneOffComponent />
      {restEntries}
    </React.Fragment>
  );
}

答案 1 :(得分:0)

问题来自您的map函数,它仅有条件地返回某些内容。这将导致每个带有index <= 0的条目都保留在数组中,然后React尝试渲染它们。

如果不满足您的条件,则应该发送一个空节点(我不知道片段是否可以工作):

render() {
    entries.sort((a, b) => b.likes - a.likes) //Does the exact same thing

    return (
        <React.Fragment>
            <Entry entryNumber={entries[0].id} />

            <OneOffComponent />
            {entries.map((entry, index) => index > 0 ? 
                <Entry key={entry.id} entryNumber={entry.id} /> 
                : 
                <div key={entry.id}/>)
            }
        }}
        </React.Fragment>
    );
}

一个更好的解决方案是使用shift从数组中取出第一个值。由于也会​​从数组中删除第一个值,因此您不再需要条件:

render() {
    return (
        <React.Fragment>
            {entries.sort((a, b) => b.likes - a.likes)}

            <Entry entryNumber={entries.shift().id} />

            <OneOffComponent />
            {entries.map(({ id }) => <Entry key={id} entryNumber={id} />)}
        </React.Fragment>
    );
}

答案 2 :(得分:0)

问题在于sort()返回排序后的数组,所以就像您在<React.Fragment>元素中输出该对象数组一样:

<React.Fragment> 
    {entries.sort((a, b) => b.likes - a.likes)}

排序本身不是问题,而是您要做的地方。因此,将排序从输出中移出:

entries.sort((a, b) => b.likes - a.likes);
return (
    <React.Fragment>

这将解决它。

NB:代替if回调中的map,只需跳过带有slice的第一个元素:

entries.slice(1).map( ......