[REACT_DOC]-Quick Start
Quick Start
概览:
- 如何创建以及嵌套组件
- 如何添加markup 和样式
- 如何展示数据
- 如何条件渲染,如何渲染列表
- 如何响应事件并更新渲染
- 如何在组件之间共享数据
创建以及嵌套组件
function MyButton() {
return (
<button>I'm a button</button>
);
}
export default function MyApp() {
return (
<div>
<h1>Welcome to my app</h1>
<MyButton />
</div>
);
}
注意: <MyButton />
以大写字母开始, React 组件始终必须以大写字母开始, 而 HTML tags 必须是小写的。
export default
关键字声明了在这个文件中的 主组件,
用 JSX 书写 标记(markup)
上面你所见到的 标记语法 被称作 JSX, JSX 相比较HTML而言,会更加的严格, 比必须关闭标签,例如 <br/>
, 你的组件也不能够 return
多个 JSX tags, 你必须将返回的标签包裹, 例如 <div>...</div>
或者 <>...</>
:
function AboutPage() {
return (
<>
<h1>About</h1>
<p>Hello there.<br />How do you do?</p>
</>
);
}
添加样式
在 React 中, 你需要通过 className
属性来执行一个标签的 class
:
<img className="avatar" />
接着, 你在一个独立的 CSS 文件中去书写CSS 样式:
/* In your CSS */
.avatar{
border-radius:50%
}
React 并没有规定你如何去添加这个CSS 文件,在最简单的情况下,你可以直接添加一个 <link>
tag 到你的 HTML 文件中,然后引入它。 如果你使用框架或者工具来构建 React项目, 那么你需要参看他们的对应文档以学习如何添加CSS 文件。
展示数据
JSX 允许你在一个花括号中插入一个变量以展示这个变量值。 例如:
return (
<h1>
{user.name}
</h1>
);
同样的, 也可以为一个标签的属性指定变量值:
return (
<img
className="avatar"
src={user.imageUrl}
/>
);
实际上, JSX 支持在花括号中解析更加复杂的表达式, 例如:
//App.js
const user = {
name: 'Hedy Lamarr',
imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg',
imageSize: 90,
};
export default function Profile() {
return (
<>
<h1>{user.name}</h1>
<img
className="avatar"
src={user.imageUrl}
alt={'Photo of ' + user.name}
style={{
width: user.imageSize,
height: user.imageSize
}}
/>
</>
);
}
在上面的示例中, style={{}}
并不是一个特殊的语法, 而是style={}
语法花括号中的一个常规的 {}
对象。
条件渲染
在 React 中, 没有特定的语法去写 条件 渲染, 替而代之, 你可以直接使用 if
条件语句去完成:
let content;
if (isLoggedIn) {
content = <AdminPanel />;
} else {
content = <LoginForm />;
}
return (
<div>
{content}
</div>
);
如果你更加喜欢简洁的代码, 那么你可以使用三元表达式:
<div>
{isLoggedIn ? (
<AdminPanel />
) : (
<LoginForm />
)}
</div>
甚至,如果你压根都不需要 else
分支,比可以使用一个简写的逻辑语法: &&
:
<div>
{isLoggedIn && <AdminPanel />}
</div>
列表渲染
我们通常依赖 的特性,像for
循环, map
去渲染一个列表元素。 例如:
const products = [
{ title: 'Cabbage', id: 1 },
{ title: 'Garlic', id: 2 },
{ title: 'Apple', id: 3 },
];
在你的组件中, 使用map()
函数去将一个数组转换为一个li
元素列表:
const listItems = products.map(product =>
<li key={product.id}>
{product.title}
</li>
);
return (
<ul>{listItems}</ul>
);
注意: <li>
有一个 key
属性 , 对于列表中的每一项, 你都应该传入一个字符串或者数字,用以标识该 项的唯一性 。这样,当随后发生了插入,删除,或者重排序,React 通过这个key 就能明白发生了什么。
const products = [
{ title: 'Cabbage', isFruit: false, id: 1 },
{ title: 'Garlic', isFruit: false, id: 2 },
{ title: 'Apple', isFruit: true, id: 3 },
];
export default function ShoppingList() {
const listItems = products.map(product =>
<li
key={product.id}
style={{
color: product.isFruit ? 'magenta' : 'darkgreen'
}}
>
{product.title}
</li>
);
return (
<ul>{listItems}</ul>
);
}
事件响应
你可以通过在你的组件中定义一个 event handler 以响应发生对应的事件。
function MyButton() {
function handleClick() {
alert('You clicked me!');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
注意: onClick={handleClick}
的末尾没有圆括号, 你只需要将这个事件的定义传入, React 将会在你随后点击这个按钮的时候再去调用这个事件。
更新屏幕
通常, 你会希望你的组件能够 “记住” 一些信息, 并展示它。 例如,或许你想要计数按钮被点击的次数。 要做到这点, 你需要添加 start
到你的组件。
首先,从 react
引入useState
:
import { useState } from "react";
现在你可以在你的组件内部声明一个 “状态” 变量:
function MyButton(){
const [count,setCount] = useState(0);
//...
}
你将会从 useState
中得到两个东西, 当前的状态(count
), 以及一个提供给你去更新它的 (setCount
)。 你可以任意定义他们的名字,但是约定俗称的,我们喜欢写作 [something, setSomething]
.
按钮第一次展示的时候, count
将会是 0
,因为你给 useState()
传入了0
, 这是它的初始值, 当你想要改变它的时候, 你需要调用 setCount()
方法, 并传入一个新的值。 :
function MyButton() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
Clicked {count} times
</button>
);
}
如果你多次渲染了相同的组件,每个组件都会维护一份自己独有的状态。
import { useState } from 'react';
export default function MyApp() {
return (
<div>
<h1>Counters that update separately</h1>
<MyButton />
<MyButton />
</div>
);
}
function MyButton() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
Clicked {count} times
</button>
);
}
记住, 每一个按钮都会 "记住" 它自己的状态,并且不会影响其它的按钮。
使用 Hooks
使用 use
开头的函数,被称作 Hooks, useState
是一个 React 内置的 Hook, 你可在这里找到更多的 Hooks( API reference. ), 你也可以通过组合已有的hook从而创建你自己的 Hooks .
Hooks 相比较其他的函数而言, Hooks 更加具有限制性。 你只能在你的组件的顶部去调用 Hooks , 如果你想要在一个条件或者循环中使用 useState
, 那么你应该抽离一个新的组件,并把Hooks 放在组件中。
在组件之间共享数据
在之前的示例中, 每个 MyButton
都有着自己独立的 count
, 但是有的时候,你会希望多个组件共享同一份数据,一处发生变化,其他地方也随之变化。
还是以这个按钮的例子来说,如果你希望两个MyButton
组件共用同一个 count
, 那么,你需要将 state
从独立的按钮组件中 提升 到同时包含这两个按钮组件的最近父级组件。
export default function MyApp() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>Counters that update together</h1>
<MyButton count={count} onClick={handleClick} />
<MyButton count={count} onClick={handleClick} />
</div>
);
}
function MyButton({ count, onClick }) {
return (
<button onClick={onClick}>
Clicked {count} times
</button>
);
}
注意,在<MyButton count="..." onClick="...">
上定义的这些属性,将会被包裹为一个对象作为参数传入给function MyButton({ count, onClick }){}
, 这个对象被称作 props
当你点击任意一个按钮的时候, 被传入的onClick
event handler 都将被触发, 也就是这个定义在 MyApp
中的handleClick
函数会被触发, 然后将count
加一。 接着,这个count 又会被传入到每个 按钮, 页面也会随之发生更新。