您是否赋予了 React.Fragment 正确的意义?

2025-06-08

您是否赋予了 React.Fragment 正确的意义?

更新:由于对标题及其内容的误解,标题已更改。我希望此更改能够满足预期,并保持健康的对话,最终让我们作为开发人员、程序员和专业人士不断成长。

在我超过 15 年的编码、编程和架构经验中,我发现有些人编写的代码没有规则或标准,有时甚至有人自以为遵循了一些规则,但实际上他们自己并没有真正遵守。我经常遇到这种情况,有时也会继续遇到。我写这篇文章是为了分享我认为的良好实践,并以此帮助我们成为优秀的专业人士

问题

如果传递的数组包含项目,则以下React代码会呈现项目列表。

function List(props) {  
  const items = props.items;

  return <ul>
    {items && items.map(i => <li key={i}>{i}</li>)}
  </ul>;
}

function App() {
    const collection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
    return <List items={collection} />;
}

ReactDOM.render(App(), document.getElementById('app'));
Enter fullscreen mode Exit fullscreen mode

你觉得这段代码有什么问题吗?这段代码运行正常,它创建了一个li以数字为值的节点。

如果数组中没有任何元素,会发生什么?ul节点也会被渲染,但其中既没有任何li节点,也没有任何元素。这不是什么大问题,但确实存在一些问题。

我们可以这样修改代码:

function List(props) {  
  const items = props.items;

  // *** notice how the code is modified and complex increases
  return items && 
        <ul>
        { items.map(i => <li key={i}>{i}</li>) }
      </ul>;
}

function App() {
    const collection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
    return <List items={collection} />;
}

ReactDOM.render(App(), document.getElementById('app'));
Enter fullscreen mode Exit fullscreen mode

与前一种情况一样,此代码运行良好,它完成了它应该做的事情。

那么,让我问与之前相同的问题,如果数组中没有项目会发生什么?

在这种情况下,false返回一个值,而不是 HTML 节点。这里的问题是,我们根据传递的属性返回不同类型的项目items

为什么这是个问题?实际上,这不仅仅是一个编码问题,而是一个概念问题。在这个函数中返回相同类型的项将使其更易于测试、维护和阅读,因为它将保持一致,并且调用此函数的其他方法将收到它们所期望的内容,而无需检查是否检索了布尔值或组件。

下一步的代码修改必须考虑到这个前提,因此它将如下所示:

function List(props) {  
  const items = props.items;

  // check if items is not empty
  const isEmpty = !(items && items.length > 0);

  // always return a React component
  return isEmpty
    ? <React.Fragment />
    : (<ul>
        { items.map(i => <li key={i}>{i}</li>) }
      </ul>);
}

function App() {
    const collection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
    return <List items={collection} />;
}

ReactDOM.render(App(), document.getElementById('app'));
Enter fullscreen mode Exit fullscreen mode

现在我们的代码看起来更合理了,不是吗?我们总是为代码采用的任何选项或路径返回一个组件。如果 items 不为空,ul则返回一个节点,并且li每个节点都包含一个节点,实际上是一个 React 组件。

如果没有条目,React.Fragment则返回一个组件。它们都是React 组件,调用者无需检查。

作为一名专业的程序员,我们必须赋予我们的对象意义和名称

你可能注意到了,我们的代码中有几个对象:一个空列表组件、一个项目列表组件、一个项目组件和一个管理器组件。每个组件都有其独特的职责(遵循我将在后续文章中讨论的单一职责原则),并且代码简洁,易于理解、维护和测试。

function ListItem(props) {
    return <li>{props.value}</li>;
}

function ItemList(props) {  
  const items = props.items;

  return <ul>
    { items.map(i => <ListItem key={i} value={i} />) }
  </ul>;
}

// As suggested by Andy Nicholson
const EmptyList = () => <React.Fragment />;

function ListManager(props) {
    const items = props.items;

  const isEmpty = items && items.length <= 0;

  return isEmpty 
    ? <EmptyList />
    : <ItemList items={items} />;
}

function App() {
    const collection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
    return <ListManager items={collection} />;
}

ReactDOM.render(App(), document.getElementById('app'));
Enter fullscreen mode Exit fullscreen mode

我觉得这段代码比第一段好多了。审阅者可以看到代码背后的人是如何思考如何面对问题、限制以及解决问题的。

总结

正如我上面几段话所写,专业的程序员必须赋予代码意义。编程任何人都可以做到,但如何以合理的方式进行编程只是专业人士的职责所在。

你觉得这篇文章的练习怎么样?
希望它能对你有所帮助,或者只是希望你读得开心。

鏂囩珷鏉ユ簮锛�https://dev.to/codbugs/professionals-never-return-react-fragment-coders-do-4kim
PREV
2025 年你需要了解的 5 个很棒的 Redis 替代品
NEXT
以酷炫的方式学习 CSS 动画