学习视频https://www.youtube.com/watch?v=SqcY0GlETPk
构建React工程
建议使用node16以上版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 PS E:\Code\React> npm create vite@4.1.0 Need to install the following packages: create-vite@4.1.0 Ok to proceed? (y) y √ Project name: ... react-app √ Select a framework: » React √ Select a variant: » TypeScript Scaffolding project in E:\Code\React\react-app... Done. Now run: cd react-app npm install npm run dev code .
浏览: http://127.0.0.1:5173/
命名规范: PascalCase
安装拓展 安装prettier
拓展
配置
然后按下快捷键 , Alt Shift F , 配置Prettier
关于Babel https://babeljs.io/repl
Presets - Option - React Runtime - Classic
输出的html代码会被babel转义成为JavaScript代码
引入bootstrap
官网: https://getbootstrap.com/
使用根标签包裹 1.div标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function ListGroup ( ) { return ( <div > <h1 > List</h1 > <ul className ="list-group" > <li className ="list-group-item" > An item</li > <li className ="list-group-item" > A second item</li > <li className ="list-group-item" > A third item</li > <li className ="list-group-item" > A fourth item</li > <li className ="list-group-item" > And a fifth one</li > </ul > </div > ); }export default ListGroup ;
2.使用Fragment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import { Fragment } from "react" ;function ListGroup ( ) { return ( <Fragment > <h1 > List</h1 > <ul className ="list-group" > <li className ="list-group-item" > An item</li > <li className ="list-group-item" > A second item</li > <li className ="list-group-item" > A third item</li > <li className ="list-group-item" > A fourth item</li > <li className ="list-group-item" > And a fifth one</li > </ul > </Fragment > ); }export default ListGroup ;
3.空着
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function ListGroup ( ) { return ( <> <h1 > List</h1 > <ul className ="list-group" > <li className ="list-group-item" > An item</li > <li className ="list-group-item" > A second item</li > <li className ="list-group-item" > A third item</li > <li className ="list-group-item" > A fourth item</li > <li className ="list-group-item" > And a fifth one</li > </ul > </> ); }export default ListGroup ;
for循环 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function ListGroup ( ) { const items = ["New York" , "San Francisco" , "Tokyo" , "London" , "Paris" ]; return ( <> <h1 > List</h1 > <ul className ="list-group" > {items.map((item) => ( <li className ="list-group-item" key ={item} > {item} </li > ))} </ul > </> ); }export default ListGroup ;
条件判断 1 2 {} {items.length === 0 && <p > Not item found</p > }
函数 1.内联
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function ListGroup ( ) { let items = ["New York" , "San Francisco" , "Tokyo" , "London" , "Paris" ]; return ( <> <h1 > List</h1 > {/* items.length === 0 ? <p > Not item found</p > : null */} {items.length === 0 && <p > Not item found</p > } <ul className ="list-group" > {items.map((item, index) => ( <li className ="list-group-item" key ={item} onClick ={(event) => console.log(event, item, index)} > {item} </li > ))} </ul > </> ); }
2.声明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import { MouseEvent } from "react" ;function ListGroup ( ) { let items = ["New York" , "San Francisco" , "Tokyo" , "London" , "Paris" ]; const handleClick = (event: MouseEvent ) => console .log (event); return ( <> <h1 > List</h1 > {/* items.length === 0 ? <p > Not item found</p > : null */} {items.length === 0 && <p > Not item found</p > } <ul className ="list-group" > {items.map((item, index) => ( <li className ="list-group-item" key ={item} onClick ={handleClick} > {item} </li > ))} </ul > </> ); }export default ListGroup ;
更新状态 定义selectedIndex变量, 使用setSelectedIndex来修改该变量
调用方式: setSelectedIndex
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import { MouseEvent , useState } from "react" ;function ListGroup ( ) { let items = ["New York" , "San Francisco" , "Tokyo" , "London" , "Paris" ]; const handleClick = (event: MouseEvent ) => console .log (event); const [selectedIndex, setSelectedIndex] = useState (-1 ); return ( <> <h1 > List</h1 > {/* items.length === 0 ? <p > Not item found</p > : null */} {items.length === 0 && <p > Not item found</p > } <ul className ="list-group" > {items.map((item, index) => ( <li className ={ selectedIndex === index ? "list-group-item active " : "list-group-item " } key ={item} onClick ={() => { setSelectedIndex(index); }} > {item} </li > ))} </ul > </> ); }export default ListGroup ;
Props传值 父组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import ListGroup from "./components/ListGroup" ;function App ( ) { let items = ["New York" , "San Francisco" , "Tokyo" , "London" , "Paris" ]; const name = "" ; if (name) return <h1 > Hello {name}</h1 > ; else return ( <div > <ListGroup items ={items} heading ="City" /> </div > ); }export default App ;
子组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import { MouseEvent , useState } from "react" ;interface Props { items : string []; heading : string ; }function ListGroup ({ items, heading }: Props ) { const handleClick = (event: MouseEvent ) => console .log (event); const [selectedIndex, setSelectedIndex] = useState (-1 ); return ( <> <h1 > {heading}</h1 > {/* items.length === 0 ? <p > Not item found</p > : null */} {items.length === 0 && <p > Not item found</p > } <ul className ="list-group" > {items.map((item, index) => ( <li className ={ selectedIndex === index ? "list-group-item active " : "list-group-item " } key ={item} onClick ={() => { setSelectedIndex(index); }} > {item} </li > ))} </ul > </> ); }export default ListGroup ;
消息传递触发函数 父组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import ListGroup from "./components/ListGroup" ;function App ( ) { let items = ["New York" , "San Francisco" , "Tokyo" , "London" , "Paris" ]; const name = "" ; const handleSelectItem = (item: string ) => { console .log (item); }; if (name) return <h1 > Hello {name}</h1 > ; else return ( <div > <ListGroup items ={items} heading ="City" onSelectItem ={handleSelectItem} /> </div > ); }export default App ;
子组件
子组件触发父组件的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 import { MouseEvent , useState } from "react" ;interface Props { items : string []; heading : string ; onSelectItem : (item: string ) => void ; }function ListGroup ({ items, heading, onSelectItem }: Props ) { const handleClick = (event: MouseEvent ) => console .log (event); const [selectedIndex, setSelectedIndex] = useState (-1 ); return ( <> <h1 > {heading}</h1 > {/* items.length === 0 ? <p > Not item found</p > : null */} {items.length === 0 && <p > Not item found</p > } <ul className ="list-group" > {items.map((item, index) => ( <li className ={ selectedIndex === index ? "list-group-item active " : "list-group-item " } key ={item} onClick ={() => { setSelectedIndex(index); onSelectItem(item); }} > {item} </li > ))} </ul > </> ); }export default ListGroup ;
将子项传递给组件 安装拓展ES7+ React/Redux/React-Native snippets
创建Alert.tsx
, 然后输入 rafce
, 然后回车 (相当于快速创建模板的快捷键)
将标签内部的内容通过children传递给了子组件
父组件App.tsx
1 2 3 4 5 6 7 8 9 10 11 12 import Alert from "./components/Alert"; function App() { return ( <div> <Alert>Hello World</Alert> </div> ); } export default App;
子组件Alert.tsx
1 2 3 4 5 6 7 8 9 10 11 12 import { ReactNode } from "react" ;interface Props { children : ReactNode ; }const Alert = ({ children }: Props ) => { return <div > {children}</div > ; };export default Alert ;
第一个小demo 父组件App.tsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import Button from "./components/Button" ;function App ( ) { return ( <> <Button color ="primary" onClick ={() => console.log("Clicked")}> Primary </Button > </> ); }export default App ;
子组件Button.tsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import React from "react" ;interface Props { children : string ; color?: "primary" | "secondary" | "danger" ; onClick : () => void ; }const Button = ({ children, onClick, color = "primary" }: Props ) => { return ( <> <button className ={ "btn btn-primary "} onClick ={onClick} > {children} </button > </> ); };export default Button ;
第二个小demo 父组件App.tsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import { useState } from "react" ;import Alert from "./components/Alert" ;import Button from "./components/Button" ;function App ( ) { const [alertVisible, setAlertVisiblity] = useState (false ); return ( <> {alertVisible && ( <Alert onClose ={() => setAlertVisiblity(false)}>Alert</Alert > )} <Button color ="primary" onClick ={() => setAlertVisiblity(true)}> Primary </Button > </> ); }export default App ;
子组件Alert.tsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import { ReactNode } from "react" ;interface Props { children : ReactNode ; onClose : () => void ; }const Alert = ({ children, onClose }: Props ) => { return ( <div className ="alert alert-primary alert-dismissible" > {children} <button type ="button" className ="btn-close" onClick ={onClose} data-bs-dismiss ="alert" aria-label ="Close" > </button > </div > ); };export default Alert ;
子组件Button.tsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import React from "react" ;interface Props { children : string ; color?: "primary" | "secondary" | "danger" ; onClick : () => void ; }const Button = ({ children, onClick, color = "primary" }: Props ) => { return ( <> <button className ={ "btn btn-primary "} onClick ={onClick} > {children} </button > </> ); };export default Button ;