React Tutorials for Beginners
Get Started
React Tutorials, Mosh, Youtube
1. 创建项目
npm create vite@latest
2. 通过 npm 安装 bootstrap
npm i bootstrap@5.2.3
main.tsx 引入全局 Bootstrap CSS
--------
import 'bootstrap/dist/css/bootstrap.css'
了解 React 目录结构及各文件的作用
了解 JSX。链接 🔗,打开后在左侧窗口输入 const p1 = <p>Hello</p>
创建并使用第一个组件
使用 Fragment 组件
渲染数据、渲染列表
动态渲染
点击事件处理
Manage State
示例:列表选中效果
import { useState } from 'react'
function ListGroup() {
let cities = ['New York', 'San Francisco', 'Tokyo', 'London', 'Paris']
// 创建状态变量,告知 React 已经渲染的组件可能随着状态的变化而变化
// useState 返回 len=2 的数组,arr[0]为状态,arr[1]为更新状态的函数
const [selectedIndex, setSelectedIndex] = useState(0)
return (
<>
<h1>ListGroup</h1>
{cities.length === 0 && <p>no item found</p>}
<ul className="list-group">
{cities.map((city, index) => (
<li
key={index}
className={
index === selectedIndex ? 'list-group-item active' : 'list-group-item'
}
onClick={() => setSelectedIndex(index)}
>
{city}
</li>
))}
</ul>
</>
)
}
export default ListGroup
Pass Data via Props
function App() {
let cities = ['New York', 'San Francisco', 'Tokyo', 'London', 'Paris']
return (
<div>
<ListGroup
cities={cities}
heading="Cities"
/>
</div>
)
}
// define Props Struct
interface MyProps {
cities: string[]
heading: string
}
// deconstruction
function ListGroup({ cities, heading }: MyProps) {
const [selectedIndex, setSelectedIndex] = useState(0)
return (
<>
<h1>{heading}</h1>
{cities.length === 0 && <p>no item found</p>}
<ul className="list-group">
{cities.map((city, index) => (
<li
key={index}
className={
index === selectedIndex
? 'list-group-item active'
: 'list-group-item'
}
onClick={() => {
setSelectedIndex(index)
}}
>
{city}
</li>
))}
</ul>
</>
)
}
Pass Function via Props
function App() {
return (
<div>
<ListGroup
onSelectCity={ (city: string) => console.log(city) }
/>
</div>
)
}
interface MyProps {
onSelectCity: (city: string) => void
}
function ListGroup({ onSelectCity }: MyProps) {
const [selectedIndex, setSelectedIndex] = useState(0)
let cities = ['New York', 'San Francisco', 'Tokyo', 'London', 'Paris']
return (
<>
<h1>{heading}</h1>
{cities.length === 0 && <p>no item found</p>}
<ul className="list-group">
{cities.map((city, index) => (
<li
key={index}
className={
index === selectedIndex
? 'list-group-item active'
: 'list-group-item'
}
onClick={() => {
setSelectedIndex(index)
onSelectCity(city) // use function from props
}}
>
{city}
</li>
))}
</ul>
</>
)
}
States VS Props
Props | States |
---|---|
Input passed to a component | Data managed by a component |
Similar to function args | Similar to local variables |
Immutable(better not to change) | Mutable |
Cause a re-render | Cause a re-render |
Passing Chidren via Props
Trick time
-
fisrtly install this Extention: ES7+ React/Redux/React-Native snippets
-
then create .tsx file and type
rafce
to generate a template
Pass html content to a component
import Alert from './components/Alert'
function App() {
return (
<div>
<Alert>
Hello <strong>World</strong>, I am the children part
</Alert>
</div>
)
}
export default App
Receive ReactNode
type children
import { ReactNode } from 'react'
interface MyProps {
children: ReactNode
}
function Alert({ children }: MyProps) {
return (
<div className="alert alert-primary" role="alert">
{children}
</div>
)
}
export default Alert
Inspect Components with React Dev Tool
Install at Chrome Extension Web Store, then restart Chrome to activate the extension.
Exercise: Build a Button Component
import { MouseEvent, ReactNode } from 'react'
interface MyProps {
children: ReactNode
handleClickEvent: (event: MouseEvent) => void
// 使用 ? 表示该参数的传递是可选择的;
// 后边使用 | 表示在进行选择时只能选择给定的几个选项之一
color?: 'primary' | 'success' | 'danger'
}
// 如果父组件未传递 color 参数,则使用给定的默认值
const Button = ({ children, handleClickEvent, color = 'primary' }: MyProps) => {
return (
<button className={'btn btn-' + color} onClick={handleClickEvent}>
{children}
</button>
)
}
export default Button
import { MouseEvent } from 'react'
import Button from './components/Button'
function App() {
const handleClickEvent = (event: MouseEvent) => {
console.log(event)
}
return (
<div>
<Button handleClickEvent={handleClickEvent}>Click on me</Button>
<Button color="danger" handleClickEvent={handleClickEvent}>Ayu</Button>
</div>
)
}
export default App
Exercise: Show and Close an Alert after Clicking Buttons
import { useState } from 'react'
import Alert from './components/Alert'
import Button from './components/Button'
function App() {
var [alertVisiable, setAlertVisiablity] = useState(false)
return (
<div>
{alertVisiable && (
<Alert onClose={() => setAlertVisiablity(false)}>Blablabla...</Alert>
)}
<Button onClick={() => setAlertVisiablity(true)} />
</div>
)
}
export default App
import { ReactNode } from 'react'
interface MyProp {
children: ReactNode
onClose: () => void
}
function Alert({ children, onClose }: MyProp) {
return (
<div className={'alert alert-warning alert-dismissible'} role="alert">
{children}
<button
type="button"
className="btn-close"
data-bs-dismiss="alert"
aria-label="Close"
onClick={onClose}
></button>
</div>
)
}
export default Alert
interface MyProp {
onClick: () => void
}
function Button({ onClick }: MyProp) {
return (
<button type="button" onClick={() => onClick()} className="btn btn-primary">
Show Alert
</button>
)
}
export default Button
沉舟侧畔千帆过,病树前头万木春。