`和`
`标签。
+:::info
+如果你熟悉 web 开发,``和``应该能让你想起 HTML。你可以把它们看作是应用开发中的``和`
`标签。
+:::
-> 在 Android 上,常见的做法是把视图放入`LinearLayout`, `FrameLayout`或是`RelativeLayout`等布局容器中来定义子元素如何排列。在 React Native 中, `View` 使用弹性盒模型(Flexbox)来为子元素布局。详情请参考[使用 Flexbox 布局](flexbox)。
+:::info
+在 Android 上,常见的做法是把视图放入`LinearLayout`, `FrameLayout`或是`RelativeLayout`等布局容器中来定义子元素如何排列。在 React Native 中, `View` 使用弹性盒模型(Flexbox)来为子元素布局。详情请参考[使用 Flexbox 布局](flexbox)。
+:::
@@ -222,8 +184,7 @@ export default Cat;
这样你就可以在别处通过``来任意引用这个组件了:
```SnackPlayer name=Multiple%20Components
-import React from 'react';
-import { Text, TextInput, View } from 'react-native';
+import {Text, View} from 'react-native';
const Cat = () => {
return (
@@ -231,7 +192,7 @@ const Cat = () => {
I am also a cat!
);
-}
+};
const Cafe = () => {
return (
@@ -242,7 +203,7 @@ const Cafe = () => {
);
-}
+};
export default Cafe;
```
@@ -253,11 +214,13 @@ export default Cafe;
## Props 属性
-**Props** 是“properties”(属性)的简写。Props 使得我们可以定制组件。比如可以给每只``一个不同的`name`:
+**Props** 是"properties"(属性)的简写。Props 使得我们可以定制组件。比如可以给每只``一个不同的`name`:
-```SnackPlayer name=Multiple%20Props
-import React from 'react';
-import { Text, View } from 'react-native';
+
+
+
+```SnackPlayer name=Multiple%20Props&ext=js
+import {Text, View} from 'react-native';
const Cat = (props) => {
return (
@@ -280,66 +243,107 @@ const Cafe = () => {
export default Cafe;
```
-React Native 的绝大多数核心组件都提供了可定制的 props。例如,在使用[`Image`](image)组件时,你可以给它传递一个[`source`](image#source)属性,用来指定它显示的内容:
+
+
+
+```SnackPlayer name=Multiple%20Props&ext=tsx
+import {Text, View} from 'react-native';
+
+type CatProps = {
+ name: string;
+};
+
+const Cat = (props: CatProps) => {
+ return (
+
+ Hello, I am {props.name}!
+
+ );
+};
+
+const Cafe = () => {
+ return (
+
+
+
+
+
+ );
+};
+
+export default Cafe;
+```
+
+
+
+
+React Native 的绝大多数 Core Component 都提供了可定制的 props。例如,在使用[`Image`](image)组件时,你可以给它传递一个[`source`](image#source)属性,用来指定它显示的内容:
```SnackPlayer name=Props
-import React from 'react';
-import { Text, View, Image } from 'react-native';
+import {Text, View, Image} from 'react-native';
const CatApp = () => {
return (
Hello, I am your cat!
);
-}
+};
export default CatApp;
```
`Image` 有[很多不同的 props](image#props),[`style`](image#style)也是其中之一,它接受对象形式的样式和布局键值对。
-> 请留意我们在指定`style`属性的宽高时所用到的双层括号`{{ }}`。在 JSX 中,引用 JS 值时需要使用`{}`括起来。在你需要传递非字符串值(比如数组或者数字)的时候会经常用到这种写法:` age={2}`。然而我们在 JS 中定义一个对象时,本来**_也_**需要用括号括起来:`{width: 200, height: 200}`。因此要在 JSX 中传递一个 JS 对象值的时候,就必须用到两层括号:`{{width: 200, height: 200}}`。
+:::note
+请留意我们在指定`style`属性的宽高时所用到的双层括号`{{ }}`。在 JSX 中,引用 JS 值时需要使用`{}`括起来。在你需要传递非字符串值(比如数组或者数字)的时候会经常用到这种写法:``。然而我们在 JS 中定义一个对象时,本来***也***需要用括号括起来:`{width: 200, height: 200}`。因此要在 JSX 中传递一个 JS 对象值的时候,就必须用到两层括号:`{{width: 200, height: 200}}`。
+:::
-使用核心组件[`Text`](text), [`Image`](image)以及[`View`](view)搭配 props 已经可以做不少东西了!但是如果想要做一些用户交互,那我们还需要用到状态(state)。
+使用 Core Component [`Text`](text), [`Image`](image)以及[`View`](view)搭配 props 已经可以做不少东西了!但是如果想要做一些用户交互,那我们还需要用到状态(state)。
## State 状态
如果把 props 理解为定制组件渲染的参数, 那么**state**就像是组件的私人数据记录。状态用于记录那些随时间或者用户交互而变化的数据。状态使组件拥有了记忆!
-> 按惯例来说,props 用来配置组件的第一次渲染(初始状态)。state 则用来记录组件中任意可能随时间变化的数据。下面示例的情景发生在一个猫咪咖啡馆中,两只猫咪正嗷嗷待哺。它们的饥饿程度会随着时间变化(相对地,它们的名字就不会变化),因此会记录在状态中。示例中还有一个喂食按钮,一键干饭,扫除饥饿状态!
+:::info
+按惯例来说,props 用来配置组件的第一次渲染(初始状态)。state 则用来记录组件中任意可能随时间变化的数据。
+:::
+
+下面示例的情景发生在一个猫咪咖啡馆中,两只猫咪正嗷嗷待哺。它们的饥饿程度会随着时间变化(相对地,它们的名字就不会变化),因此会记录在状态中。示例中还有一个喂食按钮,一键干饭,扫除饥饿状态!
-
-
+你可以使用[React 的`useState` Hook](https://react.dev/learn/state-a-components-memory)来为组件添加状态。Hook (钩子)是一种特殊的函数,可以让你"钩住"一些 React 的特性。例如`useState`可以在函数组件中添加一个"状态钩子",在函数组件重新渲染执行的时候能够保持住之前的状态。要了解更多,可以阅读[React 中有关 Hook 的文档](https://react.dev/reference/react)。
-你可以使用[React 的`useState` Hook](https://zh-hans.reactjs.org/docs/hooks-state.html)来为组件添加状态。Hook (钩子)是一种特殊的函数,可以让你“钩住”一些 React 的特性。例如`useState`可以在函数组件中添加一个“状态钩子”,在函数组件重新渲染执行的时候能够保持住之前的状态。要了解更多,可以阅读[React 中有关 Hook 的文档](https://zh-hans.reactjs.org/docs/hooks-intro.html)。
+
+
-```SnackPlayer name=State
-import React, { useState } from "react";
-import { Button, Text, View } from "react-native";
+```SnackPlayer name=State&ext=js
+import {useState} from 'react';
+import {Button, Text, View} from 'react-native';
-const Cat = (props) => {
+const Cat = props => {
const [isHungry, setIsHungry] = useState(true);
return (
- I am {props.name}, and I am {isHungry ? "hungry" : "full"}!
+ I am {props.name}, and I am {isHungry ? 'hungry' : 'full'}!
);
-}
+};
const Cafe = () => {
return (
@@ -348,36 +352,85 @@ const Cafe = () => {
>
);
-}
+};
export default Cafe;
```
+
+
+
+```SnackPlayer name=State&ext=tsx
+import {useState} from 'react';
+import {Button, Text, View} from 'react-native';
+
+type CatProps = {
+ name: string;
+};
+
+const Cat = (props: CatProps) => {
+ const [isHungry, setIsHungry] = useState(true);
+
+ return (
+
+
+ I am {props.name}, and I am {isHungry ? 'hungry' : 'full'}!
+
+
+ );
+};
+
+const Cafe = () => {
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default Cafe;
+```
+
+
+
+
首先要从 react 中引入`useState`:
-```jsx
-import React, { useState } from 'react';
+```tsx
+import {useState} from 'react';
```
然后可以通过在函数内调用`useState`来为组件声明状态。在本示例中 `useState` 创建了一个 `isHungry` 状态变量:
-```jsx
-const Cat = (props) => {
+```tsx
+const Cat = (props: CatProps) => {
const [isHungry, setIsHungry] = useState(true);
// ...
};
```
-> 你可以使用`useState`来记录各种类型的数据: strings, numbers, Booleans, arrays, objects。例如你可以这样来记录猫咪被爱抚的次数:`const [timesPetted, setTimesPetted] = useState(0)`。`useState`实质上做了两件事情:
+:::tip
+你可以使用`useState`来记录各种类型的数据: strings, numbers, Booleans, arrays, objects。例如你可以这样来记录猫咪被爱抚的次数:`const [timesPetted, setTimesPetted] = useState(0)`。
+:::
+
+`useState`实质上做了两件事情:
-- 创建一个“状态变量”,并赋予一个初始值。上面例子中的状态变量是`isHungry`,初始值为`true`。
+- 创建一个"状态变量",并赋予一个初始值。上面例子中的状态变量是`isHungry`,初始值为`true`。
- 同时创建一个函数用于设置此状态变量的值——`setIsHungry`。
取什么名字并不重要。但脑海中应该形成这样一种模式:`[<取值>, <设值>] = useState(<初始值>)`.
-下面我们添加一个按钮[`Button`](button)组件,并给它一个`onPress`的 prop:
+下面我们添加一个按钮[`Button`](button) Core Component,并给它一个`onPress`的 prop:
-```jsx
+```tsx
-
-
-老式的 class 组件在使用 state 的写法上有所不同:
-
-```SnackPlayer name=State%20and%20Class%20Components
-import React, { Component } from "react";
-import { Button, Text, View } from "react-native";
-
-class Cat extends Component {
- state = { isHungry: true };
-
- render() {
- return (
-
-
- I am {this.props.name}, and I am
- {this.state.isHungry ? " hungry" : " full"}!
-
- {
- this.setState({ isHungry: false });
- }}
- disabled={!this.state.isHungry}
- title={
- this.state.isHungry ? "Pour me some milk, please!" : "Thank you!"
- }
- />
-
- );
- }
-}
-
-class Cafe extends Component {
- render() {
- return (
- <>
-
-
- >
- );
- }
-}
-
-export default Cafe;
-```
-
-再次强调,对于 class 组件始终要记得从 React 中引入`Component`:
-
-```jsx
-import React, { Component } from 'react';
-```
-
-在 class 组件中, state 以对象的形式存放:
-
-```jsx
-export class Cat extends Component {
- state = { isHungry: true };
- //..
-}
-```
-
-和使用`this.props`获取 props 一样,在组件中获取状态也是通过`this.state`:
-
-```jsx
-
- I am {this.props.name}, and I am
- {this.state.isHungry ? ' hungry' : ' full'}!
-
-```
-
-要修改状态中的值,只需给`this.setState()`传入一个对象,包含要修改的键值对即可:
-
-```jsx
- {
- this.setState({ isHungry: false });
- }}
-/>
-```
-
-> 不要直接给组件 state 赋值(比如`this.state.hunger = false`)来修改状态。使用 `this.setState()` 方法才能让 React 知悉状态的变化,从而触发重渲染。直接修改状态变量可能会使界面无法响应!
-
-当`this.state.isHungry`为 false 时,`Button`的`disabled`属性随之被设置为`false`,它的`title`也相应变化:
-
-```jsx
-
-```
-
-最后,把你的猫放到一个咖啡店`Cafe`组件中:
-
-```jsx
-class Cafe extends Component {
- render() {
- return (
- <>
-
-
- >
- );
- }
-}
-
-export default Cafe;
-```
-
-
-
-
-> 注意到上面的`<>`和`>`了吗? 这一对 JSX 标签称为[Fragments(片段)](https://zh-hans.reactjs.org/docs/fragments.html)。由于 JSX 的语法要求根元素必须为单个元素,如果我们需要在根节点处并列多个元素,在此前不得不额外套一个没有实际用处的`View`。但有了 Fragment 后就不需要引入额外的容器视图了。
+:::info
+注意到上面的`<>`和`>`了吗? 这一对 JSX 标签称为[Fragments(片段)](https://react.dev/reference/react/Fragment)。由于 JSX 的语法要求根元素必须为单个元素,如果我们需要在根节点处并列多个元素,在此前不得不额外套一个没有实际用处的`View`。但有了 Fragment 后就不需要引入额外的容器视图了。
+:::
---
-现在你应该已经差不多了解 React 和 React Native 的核心组件与思想了。下面可以试着深入学习一些核心组件的用法,比如如何[处理文本输入``](handling-text-input)。
\ No newline at end of file
+现在你应该已经差不多了解 React 和 React Native 的核心组件与思想了。下面可以试着深入学习一些核心组件的用法,比如如何[处理文本输入``](handling-text-input)。
diff --git a/cndocs/network.md b/cndocs/network.md
index 1d8828457d8..ee67f6173b0 100644
--- a/cndocs/network.md
+++ b/cndocs/network.md
@@ -15,13 +15,13 @@ React Native 提供了和 web 标准一致的[Fetch API](https://developer.mozil
要从任意地址获取内容的话,只需简单地将网址作为参数传递给 fetch 方法即可(fetch 这个词本身也就是`获取`的意思):
-```tsx
+```ts
fetch('https://mywebsite.com/mydata.json');
```
Fetch 还有可选的第二个参数,可以用来定制 HTTP 请求一些参数。你可以指定 header 参数,或是指定使用 POST 方法,又或是提交数据等等:
-```tsx
+```ts
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
@@ -37,7 +37,7 @@ fetch('https://mywebsite.com/endpoint/', {
提交数据的格式关键取决于 headers 中的`Content-Type`。`Content-Type`有很多种,对应 body 的格式也有区别。到底应该采用什么样的`Content-Type`取决于服务器端,所以请和服务器端的开发人员沟通确定清楚。常用的'Content-Type'除了上面的'application/json',还有传统的网页表单形式,示例如下:
-```js
+```ts
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
@@ -57,7 +57,7 @@ fetch('https://mywebsite.com/endpoint/', {
网络请求天然是一种异步操作。Fetch 方法会返回一个[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise),这种模式可以简化异步风格的代码(译注:同样的,如果你不了解 promise,建议使用搜索引擎补课):
-```tsx
+```ts
const getMoviesFromApi = () => {
return fetch('https://reactnative.dev/movies.json')
.then(response => response.json())
@@ -72,7 +72,7 @@ const getMoviesFromApi = () => {
你也可以在 React Native 应用中使用`async`/`await` 语法:
-```tsx
+```ts
const getMoviesFromApiAsync = async () => {
try {
const response = await fetch(
@@ -211,9 +211,9 @@ export default App;
## 使用其他的网络库
-React Native 中已经内置了[XMLHttpRequest API](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)(也就是俗称的 ajax)。一些基于 XMLHttpRequest 封装的第三方库也可以使用,例如[frisbee](https://github.com/niftylettuce/frisbee)或是[axios](https://github.com/mzabriskie/axios)等。但注意不能使用 jQuery,因为 jQuery 中还使用了很多浏览器中才有而 RN 中没有的东西(所以也不是所有 web 中的 ajax 库都可以直接使用)。
+React Native 中已经内置了[XMLHttpRequest API](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)(也就是俗称的 ajax)。一些基于 XMLHttpRequest 封装的第三方库也可以使用,例如[frisbee](https://github.com/niftylettuce/frisbee)或是[axios](https://github.com/axios/axios)等,或者你也可以直接使用 XMLHttpRequest API。
-```tsx
+```ts
const request = new XMLHttpRequest();
request.onreadystatechange = e => {
if (request.readyState !== 4) {
@@ -239,7 +239,7 @@ XMLHttpRequest 的安全模型与网页不同,因为在原生应用中没有[
React Native 还支持[WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket),这种协议可以在单个 TCP 连接上提供全双工的通信信道。
-```tsx
+```ts
const ws = new WebSocket('ws://host.com/path');
ws.onopen = () => {