react-js 响应式
by Ryan Yurkanin
瑞安·尤卡宁(Ryan Yurkanin)
如何使用React和React-Sentinel来制作响应式,笨拙的组件 (How to use React and React-Sentinel to make responsive, dumb components)
tldr; Media Queries aren’t always enough. Element Queries are amazing, and you can black box them with a combination of render props, and something observing your element!
tldr; 媒体查询并不总是足够的。 元素查询非常了不起,您可以将它们与渲染道具和一些观察元素的组合加黑框!
处理媒体查询 (Dealing with Media Queries)
If you’ve had to recreate a Responsive Design , then you know how awesome — but troublesome — Media Queries are.
如果必须重新创建响应式设计,那么您就会知道Media Queries有多棒,但又麻烦。
Media Queries allow for CSS that only applies when size changes relative to viewport.
媒体查询允许仅在尺寸相对于视口改变时适用CSS。
Unfortunately, if you want to make a reusable and responsive card component, Media Queries are less than ideal:
不幸的是,如果您要制作可重复使用的响应式卡组件,则媒体查询就不理想了:
- You need to figure out the relationship between the height and width of the responsive card and the height and width of the viewport. 您需要弄清楚响应卡的高度和宽度与视口的高度和宽度之间的关系。
- If your card is in a more complex layout (such as a flex layout), then you need to figure out how the window size will change the flex layout, and then how that will affect the card. ? 如果您的卡片采用更复杂的布局(例如弹性布局),则需要弄清楚窗口大小将如何改变弹性布局,然后如何影响卡片。 ?
- There could be JavaScript that toggles a condition that programmatically changes the size of the card, so you would also have to factor that in and communicate that to the style sheets. 可能有JavaScript可以切换以编程方式更改卡大小的条件,因此您还必须将其考虑在内,并与样式表进行通信。
At this point, I started questioning why I even got into developing in the first place
在这一点上,我开始质疑为什么我一开始就参与开发
All I wanted was a way to style the card based on the height and width of that element. A lot of people want the ability to do that. One proposal is Element Queries, and there are a few ways out there to have them in CSS right now! ?
我想要的只是一种基于该元素的高度和宽度来设计卡片样式的方法。 许多人都希望能够做到这一点 。 一个建议是元素查询, 现在有几种方法可以将它们包含在CSS中! ?
If you’re like me, though, you want to be able to bring it into not only the JavaScript ecosystem, but the React ecosystem as well. Can we make an intelligent, black-boxed, responsive container, and a dumb visual component?
但是,如果您像我一样,不仅希望将其引入JavaScript生态系统,还希望将其引入React生态系统。 我们可以制作一个智能的,黑盒子的,响应式的容器以及一个愚蠢的视觉组件吗?
Yes we can.
是的,我们可以。
解决方案 (The solution)
The beauty of this component is that it doesn’t know why it’s the size that it is. That’s up to whomever is using it to decide, which means this component can be reused in a number of layouts. Our goal is to keep it this way, while simultaneously making it awesome.
该组件的优点在于它不知道其大小为何。 这取决于使用它来决定的人,这意味着该组件可以在许多布局中重用。 我们的目标是保持这种方式 ,同时使其表现出色。
Let’s see how we can do that by bringing in react-sentinel
, and creating a smart responsive container with it! ?
让我们看看如何通过引入react-sentinel
并使用它创建一个智能的响应容器来做到这一点! ?
So what is actually going on here?
那么,什么是真正回事?
react-sentinel
works by taking a function, the observe
prop, and calling it repeatedly in a performant requestAnimationFrame
or requestIdleCallback
loop.
react-sentinel
工作方式是使用一个函数( observe
道具),并在一个高性能requestAnimationFrame
或requestIdleCallback
循环中反复调用它。
requestAnimationFrame
loops at a speed that is determined by the browser. If someone is browsing on an older phone, the loop will happen less often. This gives the browser finer control and leads to a smoother experience!
requestAnimationFrame
以浏览器确定的速度循环。 如果有人在使用较旧的手机浏览,则循环的发生频率会降低。 这样可以给浏览器更好的控制,并带来更流畅的体验!
If you want to learn more about requestAnimationFrame
, I suggest reading Gain Motion Superpowers with requestAnimationFrame by Benjamin De Cock! ?
如果您想了解有关requestAnimationFrame
更多信息,建议阅读Benjamin De Cock的requestAnimationFrame获得运动超能力 ! ?
Sentinel
takes the return value from those functions, and if it’s different from the previous return value, sets it as the Sentinel
component’s local state. If it’s not different, then we stop right there and don’t update so we aren’t constantly re-rerendering! ?
Sentinel
从这些函数获取返回值,如果它与先前的返回值不同,则将其设置为Sentinel
组件的本地状态。 如果没什么不同,那么我们就在这里停止并且不更新,因此我们不会不断地重新渲染! ?
使用渲染道具 (Using Render Props)
Now at this point you may be asking what good is setting Sentinel
’s local state? How are we going to get that? ?
现在,您可能会问,设置Sentinel
的本地状态有什么好处? 我们如何得到它? ?
My preferred way to do this is using Render Props.
我首选的方法是使用渲染道具。
Most know that you can pass in children to a component, and access them using this.props.children
, but you could also pass in a function!
大多数人都知道可以将子级传递给组件,并使用this.props.children
访问它们,但是您也可以传递函数!
<MightHaveSecrets> {() => <WantsSecrets />}</MightHaveSecrets>
Alright, that’s a thing. Why would anyone want to do that? ?
好吧,那是一回事。 为什么有人要这样做? ?
Because now, has secrets can pass it’s internal secrets as an argument to that function! It has no idea how you are actually going to use those secrets, which makes it super encapsulated.
因为现在, 具有秘密可以将其内部秘密作为该函数的参数传递! 它不知道您将如何实际使用这些秘密,这使它成为超级封装。
<MightHaveSecrets> {secret => <WantsSecrets emoji={ secret ? ? : ? } />}</MightHaveSecrets>
All the <Sentinel
/> component cares about is polling infinitely looking to update itself. Render Props allow any chunk of UI to interpret those updates as they see fit. Also it’s a lot more obvious where those values are coming from. ?
<Sentinel
/>组件关心的所有事情都是无限轮询以寻求自我更新。 渲染道具允许UI的任何块都可以根据需要解释这些更新。 这些值的来源也很明显。 ?
If you want to learn more about Render Props, I suggest taking a look at the React Documentation or reading this article by the person who first turned me onto them!
如果您想了解有关渲染道具的更多信息,建议您看一下React文档或由第一位将我转向它们的人阅读这篇文章!
Now we have a smart component that translates the size of the element into simple props that <DumbCard
/>can digest. It’s super easy to refactor and swap values, and you don’t have to worry about what layout it lives in, or what’s going on outside of its scope.
现在,我们有了一个智能组件,可以将元素的大小转换为<DumbCard
/>可以消化的简单道具。 重构和交换值非常容易,而且您不必担心它所处的布局或范围之外的情况。
结语 (Wrapping up)
Imagine how difficult it would have been to write CSS for a card the user could resize. Now, we react to anything that changes the elements size.
想象一下,为用户可以调整大小的卡编写CSS会有多么困难。 现在,我们对改变元素大小的任何事情做出React。
The cool thing about react-sentinel
is that it doesn’t just solve the element queries problem. I’ve also used it to create a Smart Animation component, since it uses requestAnimationframe
under the hood ?
react-sentinel
在于它不仅解决了元素查询问题。 我还使用它来创建智能动画组件,因为它在requestAnimationframe
使用了requestAnimationframe
?
Here is where you can check out the code for react-sentinel
, as well as some alternative solutions!
在这里 ,您可以查看react-sentinel
的代码以及一些替代解决方案!
If you have any questions, or any topics that you’d like to see covered more in-depth feel free to hit me up! Thanks for reading and happy coding! ?
如果您有任何疑问,或者您想看到的任何主题涵盖了更深入的内容,请随时与我联系! 感谢您的阅读和愉快的编码! ?
react-js 响应式