内容简介:hi,大家好,我是Ken,目前就职于GetStream.io,为用户提供个性化可定制的feed流服务。在过去的几个月里,我一直在开发Winds 2.0,一个开源的RSS阅读器和博客订阅应用。用Node.js, Electron, Redux and React开发,并且截止发文(2018-7-11),在Github上已经拥有了超过5000个star。如果你想看看整个项目,可以访问getstream.io/winds/,或者查看在Winds中,我们在一些特定的情况需要用到
hi,大家好,我是Ken,目前就职于GetStream.io,为用户提供个性化可定制的feed流服务。
在过去的几个月里,我一直在开发Winds 2.0,一个开源的RSS阅读器和博客订阅应用。用Node.js, Electron, Redux and React开发,并且截止发文(2018-7-11),在Github上已经拥有了超过5000个star。如果你想看看整个项目,可以访问getstream.io/winds/,或者查看 github.com/GetStream/w… 上的源代码。
在Winds中,我们在一些特定的情况需要用到 React Fragments 。React Fragments是一个去年年底React v16.2.0发布的简洁小功能——它真的非常小,但是只要你了解了它,就可以在遇到一些非常具体的布局和样式情况时避开很多的麻烦。
Okay, 什么是React Fragment?
让我们稍微回顾一下 - 我确信每个React开发人员都会在他们职业生涯的某个阶段遇到这种情况(或者即将遇到):
class App extends React.Component {
render() {
return (
<p>I would</p>
<p>really like</p>
<p>to render</p>
<p>an array</p>
);
}
}
复制代码
看起来挺不错,但是当我们通过JSX转换器 运行它时......
Failed to compile.
./src/App.js
Syntax error: Adjacent JSX elements must be wrapped in an enclosing tag (6:8)
4 | return (<p>I would
5 | </p>
6 | <p>
| ^
7 | really like
8 | </p>
9 | <p>
复制代码
JSX转换器 并不喜欢这样
这背后究竟发生了什么?JSX 把所有的 <div> s和 <MyComponent> s都放进 React.createElement() 中调用——当JSX转换器看到的(最外层如果)是多个元素而不是单个元素时,它就不知道到底要渲染哪个tag,更多: React.createElement in the React documentation 。
那么我们该怎么办?每次我们需要将几个元素包装在一起时都会这样做,——Pinky,用一个 div 包裹起来!就像web开发者从div被发明出来一直以来做的那样,在DOM中嵌套另外一个 div 也无伤大雅。
class App extends React.Component {
render() {
return (
<div>
<p>I would</p>
<p>really like</p>
<p>to render</p>
<p>an array</p>
</div>
);
}
}
复制代码
嗯,问题确实解决了。但事实证明,还有另一种方法可以在一个React组件里渲染出这一组内容——通过让 render 方法返回一个节点数组。
class App extends React.Component {
render() {
return [
<p>I would</p>,
<p>really like</p>,
<p>to render</p>,
<p>an array</p>
];
}
}
复制代码
如果我们返回这样的一个元素数组,React将会转换并渲染它,而且没有 wrapper<div> (容器div)。 显得很整齐!
(还记得 JSX 转换器是如何将 <div> 和 <MyComponent> 转换并被 React.createElement() 调用的吗?在这种情况下,转换器只是将这些一个数组内的元素作为子元素直接附加到父元素,而不是当做没有父元素包含的元素数组。React v16.0.0引入了此功能。
因为这样,Dan Abramov和一些React团队的聪明人看到之后说,
“Okay,所以你可以用两种不同的方式来渲染一个元素数组 - 通过在DOM中引入一个额外的 <div> ,或者使用一些笨重的非JSX语法。这些都无法带来一个良好的编程体验。”
所以,在v16.2.0, React发布了React Fragments
okay,nowwhat’s a React Fragment?
这才是是使用React Fragment的正确方法:
class App extends React.Component {
render() {
return (
<React.Fragment>
<p>I would</p>
<p>really like</p>
<p>to render</p>
<p>an array</p>
</React.Fragment>
);
}
}
复制代码
看 - 我们写的就像 wrapper<div> 的方式一样,但在功能上与 数组渲染 方式相同,只不过是使用了看起来不错的JSX语法。 这样就可以将这些p元素呈现为数组,而不包含任何类型的 wrapper<div> 。
使用 React Fragments 还有另一种更简洁的语法:
class App extends React.Component {
render() {
return (
<>
<p>I would</p>
<p>really like</p>
<p>to render</p>
<p>an array</p>
</>
);
}
}
复制代码
可能在你的工具,linters,构建流程等等中,还没有起作用。但是发版说明中提到,这种语法的支持已经在开发中了,但是我注意到在 create-react-app 中还没有支持。
Okay,但什么时候才能使用它们呢?
在你需要摆脱 wrapper<div> 的时候。
就是这样 - 如果你发现自己处于一个 wrapper<div> 搞乱你的React组件布局的情况下,请使用React Fragment。
所以,就是当你想转换这个:
<div class="app">
(...a bunch of other elements)
<div> (my react component)
<ComponentA></ComponentA>
<ComponentB></ComponentB>
<ComponentC></ComponentC>
</div>
(...a bunch more elements)
</div>
复制代码
到这样:
<div class="app">
(...a bunch of other elements)
<ComponentA></ComponentA>
<ComponentB></ComponentB>
<ComponentC></ComponentC>
(...a bunch more elements)
</div>
复制代码
Example: 2×2 CSS grid
在Winds 2.0中,我们大量的使用了CSS Grid布局,这是博客或者RSS源网站很常见的布局。
如果您还不了解CSS Grid布局,下面的代码可以让您快速了解CSS的布局
.grid {
display: grid;
grid-template-areas:
'topnav header'
'subnav content';
grid-gap: 1em;
}
复制代码
Okay,让我们来解释一下:
- 在左上角,我们有标志或者顶级导航位。
- 在左下角,有子导航,可以响应全局和局部状态的一些变化,如“高亮”状态,tabs或折叠导航。
- 在右侧,有一些需要在屏幕上显示的内容,在Winds中,有点类似于与文章列表或文章内容配对的RSS提要或文章标题。 这两个部分将是单一的React组件 - 两个组件的道具都会根据URL导航进行更改。
所有这些作用于全局的组件(redux + URL)和本地状态的交互都略有不同。 这个视图的结构使得我们有三个React组件互为兄弟:
<div className="grid">
<TopNav />
<SubNav />
<ContentComponent />
</div>
复制代码
但是,我们希望实际呈现给页面的有四个元素:
<div class="grid">
<div class="topnav" />
<div class="subnav" />
<div class="header" />
<div class="content" />
</div>
复制代码
这......就是没有React Fragments的问题。想象一下,我们正在创建2×2网格视图的两个右侧部分的组件,即 ContentComponent :
class ContentComponent extends React.Component {
render() {
return (
<div>
<div className="header"/>
<div className="content"/>
</div>
);
}
}
复制代码
如果我们将渲染的内容包装在 <div> 中,那么我们将获得以下渲染输出:
<div class="grid">
<div class="topnav" />
<div class="subnav" />
<div>
<div class="header" />
<div class="content" />
</div>
</div>
复制代码
这不起作用 - 它还会搞乱CSS的grid布局。 从浏览器的角度来看,网格中只有3个项目,其中一个还没有 grid-area 的样式。
还记得我们应该使用React Fragments吗? 每当我们想要摆脱 wrapper<div> 。 如果我们将 ContentComponent 包装在React Fragments中而不是 wrapper<div> 中:
class ContentComponent extends React.Component {
render() {
return (
<React.Fragment>
<div className="header"/>
<div className="content"/>
</React.Fragment>
);
}
}
复制代码
然后我们将看到另外一种渲染输出:
<div class="grid">
<div class="topnav" />
<div class="subnav" />
<div class="header" />
<div class="content" />
</div>
复制代码
这就符合我们的预期了! 没有 wrapper<div> ,我们的4个元素从3个React组件渲染,浏览器看到所有元素具有正确的 grid area 样式,并且我们的CSS grid正确呈现。
很整齐! 现在怎么办?
React Fragments不是近期React版本中发布的最重要的功能,但它们在某些特定情况下非常有用。 只要了解React Fragments的存在,您就可以节省数小时的谷歌引起的头痛。这可以让我们以JSX-y方式呈现元素或者组件数组,这可以解决大量的表格、列表和CSSgrid的布局和样式问题!
以上所述就是小编给大家介绍的《React Fragments – wrapper div终结者》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- GitHub 开源神器:堪称作业终结者!
- 盗版猖獗时代,谁会成为终结者
- Kubernetes Dashboard 终结者:KubeSphere
- ddd-lite-codegen 样板代码终结者
- “性能问题终结者”Olympic,解决用户痛点背后的秘密是......
- 扫码支付勒索病毒终结者:腾讯电脑管家首创无密钥解密
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
数据结构、算法与应用
(美)Sartaj Sahni / 汪诗林、孙晓东、等 / 机械工业出版社 / 2000-01 / 49.00
本书是关于计算机科学与工程领域的基础性研究科目之一――数据结构与算法的专著。 本书在简要回顾了基本的C++ 程序设计概念的基础上,全面系统地介绍了队列、堆栈、树、图等基本数据结构,以及贪婪算法、分而治之算法、分枝定界算法等多种算法设计方法,为数据结构与算法的继续学习和研究奠定了一个坚实的基础。更为可贵的是,本书不仅仅介绍了理论知识,还提供了50多个应用实例及600多道练习题。 本书......一起来看看 《数据结构、算法与应用》 这本书的介绍吧!