react和react2
I’ve recently started working on an Android application, and as a React developer, I made the easy choice to use and test React Native to do so because it helped me stay in my comfort zone and also gives me the opportunity to explore iOS someday.
我最近开始从事Android应用程序的工作,作为React开发人员,我做出了使用和测试React Native的简单选择,因为它有助于我停留在舒适的环境中,并且有一天我有机会探索iOS 。
Even if it is the same framework, using React for native applications is a little bit different than React on the web.
即使是相同的框架,将React用于本机应用程序也与Web上的React有所不同。
I’m writing this article to share the main differences I have found between the two platforms along with a few tips I had to figure out to obtain the desired final behavior.
我正在写这篇文章,以分享我在两个平台之间发现的主要差异,以及一些我必须弄清楚以获得所需最终行为的技巧。
查看或文本-没有div (View or Text — There Is No div)
When working on a web application, we mostly use div
and span
tags for many usages. Since we are not on the web, this is no longer a possibility.
在Web应用程序上工作时,我们通常将div
和span
标签用于许多用途。 由于我们不在网络上,因此不再可能。
Instead, the content is made with View
and Text
that we could associate with the two tags above, but they have some additional constraints.
取而代之的是,内容是使用“ View
和“ Text
,我们可以将它们与上述两个标签关联,但是它们还有一些其他限制。
视图元素 (The View element)
With the View
element, you can’t add anything else inside other than components. That means it cannot contain text, which the Text
component is for. As an unfortunate consequence, it has a larger tree in your application, but it helps to separate concerns between layout and text.
使用View
元素,除了组件之外,您无法在内部添加任何其他内容。 这意味着它不能包含Text
组件用于的Text
。 不幸的是,它在您的应用程序中有一棵更大的树,但是它有助于将布局和文本分开。
import React from "react";
import { Text, View } from "react-native";
export default function HelloWorld() {
return (
<View>
<Text>Hello world</Text>
</View>
);
}
Based on the previous point, you can easily figure out that you can’t apply text-related styles to a View
component. The text styles like color
or fontSize
need to be applied to the Text
component.
根据上一点,您可以轻松地确定不能将与文本相关的样式应用于View
组件。 需要将诸如color
或fontSize
类的文本样式应用于Text
组件。
import React from "react";
import { Text, View } from "react-native";
export default function Styling() {
return (
<View style={{ backgroundColor: "rgb(255, 192, 16)" }}>
<Text style={{ color: "rgba(48, 48, 48)" }}>Hello world</Text>
</View>
);
}
View
is also a flexbox container that can only support two display values: none
or flex
. It can change numerous things if you are not confident with the model, but it is much more powerful than the classic block model used by default on the DOM.
View
也是一个flexbox容器,只能支持两个显示值: none
或flex
。 如果您对模型不满意,它可以改变很多事情,但是它比DOM默认使用的经典块模型强大得多。
You can learn more about this layout system on CSS-Tricks. Every flex property is supported in React Native, from align-items
to flex-grow
.
您可以在CSS-Tricks上了解有关此布局系统的更多信息。 从align-items
到flex-grow
,React Native都支持每个flex属性。
There is, however, one major difference between the web version and the native version: the default value of flex-direction
. If we have row
on the web, it is set to column
in React Native. Basically, this means that elements are placed by default from top to bottom instead of left to right.
但是,Web版本和本机版本之间有一个主要区别: flex-direction
的默认值。 如果我们在网上有row
,则在React Native中将其设置为column
。 基本上,这意味着默认情况下元素是从上到下而不是从左到右放置的。
import React from "react";
import { Text, View } from "react-native";
export default function Flex() {
return (
<View style={{ flexDirection: "row", alignItems: "center" }}>
<Text>✓</Text>
<Text style={{ flexGrow: 1 }}>Hello world</Text>
</View>
);
}
Finally, View
is not clickable. If you need a click behavior on it, you’ll have to wrap it into a Touchable*
component:
最后, View
不可单击。 如果需要单击行为,则必须将其包装到Touchable*
组件中:
TouchableHighlight
to add a background color on click.TouchableHighlight
在单击时添加背景色。TouchableOpacity
to reduce opacity on click.TouchableOpacity
减少点击的不透明度。TouchableWithoutFeedback
to have no feedback on click, which I don’t recommend for user experience reasons.TouchableWithoutFeedback
不会获得有关点击的反馈,出于用户体验的原因,我不建议这样做。TouchableNativeFeedback
(only on Android) to have the ripple effect on the button.TouchableNativeFeedback
(仅适用于Android)可在按钮上产生波纹效果。
import React, { useState } from "react";
import { Text, TouchableHighlight, View } from "react-native";
export default function MyClickableComponent() {
const [clicked, setClicked] = useState(false);
return (
<TouchableHighlight
activeOpacity={0.6}
onPress={() => setClicked(true)}
underlayColor="rgba(0, 0, 0, 0.3)"
>
<View>
<Text>{clicked ? "Click me" : "Clicked"}</Text>
</View>
</TouchableHighlight>
);
}
文字元素(The Text element)
If we can easily compare the Text
element to a span
tag on the web, the difference is as noticeable as with views.
如果我们可以轻松地将Text
元素与Web上的span
标签进行比较,则差异与视图一样明显。
The Text
element — as it is aptly named — exists only to make the rendering of text contents. We cannot use it for any layout-related stuff we might need. Therefore, display: "flex"
will have no effect. Neither will position
.
恰当地命名为Text
元素,其存在仅是为了呈现文本内容。 我们不能将其用于可能需要的任何与布局有关的东西。 因此, display: "flex"
将无效。 都不会position
。
However, the Text
inherits styles from the parent Text
component like it does on the web.
但是,“ Text
从父“ Text
组件继承样式,就像在网络上一样。
import React from "react";
import { Text } from "react-native";
export default function TextInherit() {
return (
<Text style={{ fontSize: 18 }}>
<Text style={{ color: "#0000ff" }}>
<Text>A blue text, sized 18</Text>
</Text>
</Text>
);
}
Like View
, the Text
component is not clickable. If that’s a behavior you need, you will have to wrap into one of the Touchable*
components.
与View
一样, Text
组件不可单击。 如果这是您需要的行为,则必须包装到其中一个Touchable*
组件中。
Finally, Text
is only meant to contain text and other Text
components. You should not include layout-related components like View
, ScrollView
, or FlatList
.
最后, Text
仅包含文本和其他Text
组件。 您不应包含与布局相关的组件,例如View
, ScrollView
或FlatList
。
用TextInput替换输入 (Replace Input With TextInput)
Since the Native API is not DOM, we do not have input
elements either, but React provides a component for the times when we need a form.
由于本机API不是DOM,因此我们也没有input
元素,但是React在需要表单时提供了一个组件。
The InputField
component works the same as input
but also has a onChangeText
attribute that accepts a callback with the value as an argument. No more need for event.target.value
!
InputField
组件的功能与input
相同,但具有onChangeText
属性,该属性接受以值作为参数的回调。 不再需要event.target.value
!
import React, { useState } from "react";
import { TextInput } from "react-native";
export default function InputForm() {
const [beerName, setBeerName] = useState("");
return (
<TextInput value={beerName} onChangeText={setBeerName} />
);
}
CSS用法(The CSS Usage)
If I’m using CSS Modules when I’m working on a web application, it is a bit different on native, where the CSS usage is more the CSS-in-JS way. The stylesheets are created with the StyleSheet.create
method that is provided by React Native and is a key/value object of class/styles for the component.
如果我在处理Web应用程序时使用CSS模块,则本机版本与本机版本有所不同,本机版本中CSS的用法更多是CSS-in-JS方式。 样式表是由React Native提供的StyleSheet.create
方法创建的,它是组件的类/样式的键/值对象。
import React from "react";
import { StyleSheet, Text, View } from "react-native";
const styles = StyleSheet.create({
layout: {
backgroundColor: "rgb(255, 192, 16)"
},
text: {
color: "rgba(48, 48, 48)"
}
});
export default function Styling() {
return (
<View style={styles.layout}>
<Text style={styles.text}>Hello world</Text>
</View>
);
}
If there are units in CSS, there are not in React Native — or more precisely, units are always set in dp
, so the render will be right even if the phones do not all have the same pixel ratio. It makes the CSS usage a bit different, but if you want to make things simpler, just consider them pixels.
如果CSS中有单位,那么React Native中就没有单位,或者更确切地说,单位总是在dp
设置,因此即使手机并非都具有相同的像素比,渲染也将正确。 它使CSS的用法有些不同,但是如果您想简化一些事情,只需考虑一下像素。
If we used to have shortcuts in CSS, it is not the same in React Native: padding
must be a number and not a list of values in a string, backgroundColor
is used for the color, and so on.
如果我们曾经在CSS中使用快捷方式,那么在React Native中就不一样了: padding
必须是数字,而不是字符串中的值列表, backgroundColor
用于颜色,依此类推。
To illustrate that rule, assume that the CSS padding: "8 16"
is not valid, and so background: "#333333"
.
为了说明该规则,假设CSS padding: "8 16"
无效,因此background: "#333333"
。
Even if these are a bit longer to type in, I find it way more explicit than the shortcuts we are used to. Plus, they are always complicated to understand for a beginner.
即使输入的时间更长,我发现它比我们过去使用的快捷方式更明确。 另外,对于初学者来说,它们总是很难理解。
After a couple of hours, I had definitely adopted this new way of writing CSS.
几个小时后,我肯定采用了这种新CSS编写方式。
import React from "react";
import { StyleSheet, Text, View } from "react-native";
const styles = StyleSheet.create({
layout: {
backgroundColor: "rgb(255, 192, 16)",
paddingLeft: 8,
paddingRight: 8,
},
wrapper: {
padding: 16,
},
text: {
color: "rgba(48, 48, 48)"
}
});
export default function Styling() {
return (
<View style={styles.layout}>
<View style={styles.wrapper}>
<Text style={styles.text}>Hello world</Text>
</View>
</View>
);
}
可缩放矢量图形(Scalable Vector Graphics)
If SVG is used a lot on the web, it is not natively supported in React Native. We need to use it with an external package: react-native-svg
.
如果SVG在网络上大量使用,则React Native本身不支持它。 我们需要将其与外部软件包一起使用: react-native-svg
。
However, the package is made to be used exactly like on the web with just a little difference: the first uppercase character.
但是,该程序包的用法与在网络上完全一样,只是略有不同:第一个大写字符。
import React from "react";
import { Svg, Path } from "react-native-svg";
export default function UsingSvg() {
return (
<Svg height="20" width="20" viewBox="0 0 24 24">
<Path d="M4 4 H 20 V 20 H 4 L 4 4" fill="#ffb010" />
</Svg>
);
}
溢出(Overflow)
If you want a scrollable View
, you need to switch to the ScrollView
component. It acts the same but has a scrollbar built in.
如果要使用可滚动的View
,则需要切换到ScrollView
组件。 它的作用相同,但是内置了滚动条。
Since the component has a vertical scroll by default, you can use the horizontal
attribute to make it scroll on the x-axis.
由于默认情况下组件具有垂直滚动,因此您可以使用horizontal
属性使其在x轴上滚动。
For performance reasons, you can also use theFlatList
component, which is a bit more complicated to use, but it will make your long lists scroll fast. If it is something you need, I encourage you to look at the official documentation.
出于性能原因,您还可以使用FlatList
组件,该组件使用FlatList
稍微复杂一些,但是它将使长列表快速滚动。 如果需要,建议您查看官方文档。
技巧和窍门 (Tips and Tricks)
可触摸的组件应用于单个元素(Touchable components are applied to a single element)
If you get the error Error: React.Children.only expected to receive a single React element child
, then you just need to wrap your elements in a new View
component.
如果出现Error: React.Children.only expected to receive a single React element child
,则只需将元素包装在新的View
组件中。
It seems pretty obvious what to do, but it can be a bit disturbing when coming from the web: When using Touchable*
components, you need to have a single layout item.
看起来很明显该怎么办,但是从网络上来时可能会有些Touchable*
:使用Touchable*
组件时,您需要一个布局项。
Text
中的Text
(Line breaks in Text
)
On the web, new lines are made with <br />
, but since native is not DOM, you can simply use {"\n"}
in your Text
components or directly in a string (e.g. <Text>{"Hello\nworld!"}</Text>
).
在网络上,用<br />
行了,但是由于native不是DOM,因此您可以在Text
组件中或直接在字符串中使用{"\n"}
(例如<Text>{"Hello\nworld!"}</Text>
)。
文字检视 (Views in Text)
You cannot have View
elements in Text
elements. This throws the following error: Cannot add a child that doesn't have a YogaNode to a parent without a measure function!
.
您不能在Text
元素中包含View
元素。 这将引发以下错误: Cannot add a child that doesn't have a YogaNode to a parent without a measure function!
。
It might make your tree a bit more complex with some code duplication, but you should always find a way to avoid this message.
某些代码重复操作可能会使您的树变得更复杂,但是您应该始终找到避免该消息的方法。
结论 (Conclusion)
Even though React Native is based on React, there are plenty of differences. On one hand, we use React on the web and use the DOM API. On the other hand, we use the native layouts for Android, iOS, and others. But it is still very easy to get into. Do not hesitate to give it a try!
即使React Native是基于React的,也存在很多差异。 一方面,我们在网络上使用React并使用DOM API。 另一方面,我们将原生布局用于Android,iOS和其他平台。 但是仍然很容易进入。 不要犹豫,试试看!
翻译自: https://medium.com/better-programming/my-journey-from-react-to-react-native-e876c31a46a4
react和react2