React Tutorials for Beginners

发布时间 2023-09-23 23:50:06作者: Egu0

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

  1. **fisrtly install this Extention: ** ES7+ React/Redux/React-Native snippets

  2. **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
screenshot

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