1.React开发环境搭建
执行 npx create-react-app 项目名称 命令来创建项目
2.实现列表渲染
在react中可以通过在{}中写入js表达式来执行js代码,所以可以通过如下手段来执行来实现列表的渲染。
function App() {let list = [{id:1,name:"Vue"},{id:2,name:"React"},{id:3,name:"Angular"}]return (<div className="App">{list.map((item)=>{return <p key={item.id}>{item.name}</p>})}</div>);
}
3.实现基础条件渲染
在react中可以通过逻辑与“&&”或者三元运算符来实现基础的条件渲染
function App() {let isLogin = falsereturn (<div className="App">{isLogin && <span>用户已登录</span>}{isLogin ? <span>用户已登录</span> : <span>用户未登录</span>}</div>);
}
4.实现复杂的条件渲染
复杂的条件渲染可以通过定义函数在函数中进行
function App() {let isLogin = 2const getLoginState = () => {if (isLogin === 0) {return <span>用户未登录</span>} else if (isLogin === 1) {return <span>用户已登录</span>} else {return <span>用户登录失效</span>}}return (<div className="App">{getLoginState()}</div>);
}
5.react中事件的绑定
在react中可以通过onClick来绑定点击事件如下:
function App() {const handleClick = ()=>{console.log("点击我")}return (<div className="App"><button onClick={handleClick}>点击我</button></div>);
}
如果需要使用事件对象参数,则需要在函数中添加参数e
function App() {const handleClick = (e)=>{console.log("事件对象参数",e)}return (<div className="App"><button onClick={handleClick}>点击我</button></div>);
}
如果要使用自定义参数则需要进行如下修改
function App() {const handleClick = (val) => {console.log("自定义参数",val)}return (<div className="App"><button onClick={()=>{handleClick("hello")}}>点击我</button></div>);
}
下面则是既需要事件对象参数,又需要自定义参数的例子
function App() {const handleClick = (val,e) => {console.log("自定义参数",val)console.log("事件对象参数",e)}return (<div className="App"><button onClick={(e)=>{handleClick("hello",e)}}>点击我</button></div>);
}
5.react中基础组件的使用
通过使用函数来定义组件,但是注意作为组件的函数必须要开头大写
function App() {const Button = ()=>{return <botton>基础按钮</botton>}return (<div className="App"><Button></Button></div>);
}
6.useState的使用
useState是一个React Hook,它允许我们向组件添加一个状态变量,从而控制影响组建的渲染结果,使用方法如下
import {useState} from 'react'function App() {let [num,setNum] = useState(1)let [person,setPerson] = useState({name:"小花",age:20})// num++const handleAdd = ()=>{setNum(num+1)}// 修改personconst updatePerson = ()=>{setPerson({...person,name:"KK"})}return (<div className="App"><span>{num}</span><span>{person.name}</span><button onClick={()=>handleAdd()}>num+1</button><button onClick={()=>updatePerson()}>修改用户名</button></div>);
}
7.基础样式的控制
react的基础样式控制有两种方法,行类样式和class类名控制,分别如下
行类样式(不推荐)
<div style={{ color: 'red' }}>测试内容</div>
class类名控制
.foo {color: red;
}
<div className='foo'>测试内容</div>
8.组件通信
父传子,在父组件中绑定数据,在子组件中的props中接收数据
// 父传子
function Son(props) {console.log(props)return <div>this is Son</div>
}function App() {let name = "app name"return (<div className="App"><Son name = {name}></Son></div>);
}
子组件中嵌入的标签可以通过props中的children属性获取
function Son(props) {console.log(props)console.log(props.children)return <div>this is Son</div>
}function App() {let name = "app name"return (<div className="App"><Son name = {name}><span>this is span</span></Son></div>);
}
子传父,在组件中调用父组件中的函数并传递参数
// 子传父
function Son(props) {let name = "this is son"return <div><button onClick={()=>{props.onGetMsg(name)}}>获取数据</button></div>
}function App() {const getMsg = (msg)=>{console.log(msg)}return (<div className="App"><Son onGetMsg = {getMsg}></Son></div>);
}
兄弟间的组件通信,可以通过子传父,然后再由父传子来实现
使用context机制跨层传递数据
import './App.css';// 1.createContext方法创建一个上下文对象
import { createContext, useContext } from 'react'const MsgContext = createContext();// 2.在顶层组件通过Provider组件提供数据
// 3.在底层组件通过useContent钩子函数使用数据function A(props) {return <div>this is A<B></B></div>
}function B(props) {const msg = useContext(MsgContext)return <div>this is B{msg}</div>
}function App() {let msg = "app msg"return (<div className="App"><MsgContext.Provider value={msg}><A></A></MsgContext.Provider></div>);
}export default App;
9.useEffect依赖项参数说明
useEffect是React中的一个钩子函数,用于处理副作用操作。副作用是指在组件渲染过程中,可能会对外部环境产生影响的操作,比如数据获取、订阅事件、操作DOM等。
useEffect副作用函数的执行时机存在多种情况,根据传入依赖项的不同,会有不同的执行表现,
没有依赖项:组件初始渲染+组件更新时执行
空数组依赖:只在初始渲染时执行一次
添加特定依赖项:组件初始渲染+特点依赖项变化时执行
useEffect清除副作用,比如在useEffect中开启了一个定时器,我们想在组件卸载时把这个定时器再清理掉,这个过程就是清理副作用,例子如下
useEffect(()=>{let timer = setInterval(()=>{console.log("定时器执行中......")},1000)return ()=>{// 清除副作用(组件卸载时)clearInterval(timer)}})
10.自定义hook的实现
使用use...前缀命名自定义hooks。
自定义hooks应该使用use关键字作为前缀。
自定义hooks应该在函数组件或自定义hooks中调用其他hooks。
确保自定义hooks内部的状态更新正确,避免陷阱如悬挂的状态。
例子如下:
function useToggle() {const [value, setValue] = useState(true)const toggle = () => setValue(!value)return {value,toggle}
}function App() {const { value, toggle } = useToggle()return (<div className="App"></div>);
}
11.Redux教程
Redux是一种状态管理工具,类似于vue3的Pinia。官网推荐使用Redux Toolkit工具来应用Redux,通过命令npm install @reduxjs/toolkit react-redux安装相关依赖。接下来相关步骤如下:
1.代码分层
2.提供reducer模块
import { createSlice } from '@reduxjs/toolkit'const counter = createSlice({//命名空间,name的值会作为action type前缀name: "counter",initialState: {count: 0,list: []},// 1/定义reducer更新状态函数 2、组件中dispatch使用的action// 内置了状态不可变的插件reducers: {// 同步add(state, action) {console.log(state, action);state.count++},sub(state) {state.count--},pus(state, action) {state.list.push(Math.floor(Math.random() * 1000))},del(state, action) {state.list.splice(action.payload, 1)}}
})
// 淡出action函数
export const { add, sub, pus, del } = counter.actions// 定义一个异步action
export const subAsync = (payload) => {return async (dispatch, getState) => {setTimeout(() => {dispatch(sub())}, 3000)}
}
// 导出reducer生成store
export default counter.reducer
3.创建store
// 创建store
import { configureStore } from '@reduxjs/toolkit'
import counter from './modules/counter'
export const store = configureStore({reducer: {counter}
})
4.在入口集成Redux
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';// 引入store和Provider
import { store } from './store';
import { Provider } from 'react-redux';const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Provider store={store}><App /></Provider>
);reportWebVitals();
5.在组件中获取状态和更新状态
import './App.css';
import { useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { add, subAsync, pus, del } from './store/modules/counter'function App() {const dispatch = useDispatch()const { count, list } = useSelector(state => state.counter)return (<div><ul><li>{count}</li><li onClick={() => {dispatch(add())}}><button>add</button></li><button onClick={() => {dispatch(subAsync())}}>-1</button></ul><hr /><ul>{list.map((item, index) =><li key={index} onClick={() => {dispatch(del(index))}}>{item}</li>)}<button onClick={() => { dispatch(pus()) }}>添加</button></ul></div>);
}export default App;
12.ReactRouter教程
1.搭建路由
执行命令npm i react-router-dom安装路由相关依赖,接下来在src文件夹下创建router文件并在其内创建路由文件index.js如下图所示:
接下来在路由文件中进行路由配置
import Login from "../pages/Login";
import App from "../App";import { createBrowserRouter } from "react-router-dom";const router = createBrowserRouter([{path:'/login',element:<Login/>},{path:'/index',element:<App/>}
])export default router
在这之后,在项目的入口文件中引入RouterProvider和router并进行配置,这样基本的路由配置就完成了
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import reportWebVitals from './reportWebVitals';
import { RouterProvider } from "react-router-dom";
import router from './router';// 引入store和Provider
import { store } from './store';
import { Provider } from 'react-redux';const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Provider store={store}><RouterProvider router={router}></RouterProvider></Provider>
);reportWebVitals();
2.路由的跳转
路由的跳转分为两种写法,一个是声明式的写法,用Link标签。一个是命令式的写法用useNavigate
import './index.css';
import { Link,useNavigate } from 'react-router-dom';function Login() {const navigate = useNavigate()return (<div>我是登录页<Link to="/index">跳转首页</Link><button onClick={()=>{navigate("/index")}}>跳转首页</button></div>);
}export default Login;
3.路由跳转传参
路由跳转传参也分为两种
searchParams传参
<button onClick={()=>{navigate("/index?id=100&name=Tom")}}>跳转首页</button>
import { useSearchParams } from 'react-router-dom';
import './App.css';function App() {const [params] = useSearchParams()console.log(params.get('id'))console.log(params.get('name'))return (<div>我是首页</div>);
}export default App;
params传参
const router = createBrowserRouter([{path:'/login',element:<Login/>},{path:'/index/:id/:name',element:<App/>}
])
<button onClick={()=>{navigate("/index/100/Tom")}}>跳转首页</button>
import { useParams } from 'react-router-dom';
import './App.css';function App() {const params = useParams()console.log(params)return (<div>我是首页</div>);
}export default App;
4.ReactRouter的嵌套路由配置
使用children属性配置路由嵌套关系,使用<Outlet>组件配置二级路由渲染位置
const router = createBrowserRouter([{path:'/login',element:<Login/>},{path:'/index',element:<App/>,children:[{path:"ArticleManage",element:<ArticleManage/>}]}
])
import { useParams } from 'react-router-dom';
import './App.css';
import { Outlet } from 'react-router-dom';function App() {const params = useParams()console.log(params)return (<div>我是首页————————————————<Outlet/></div>);
}export default App;
5.ReactRouter的默认二级路由配置
当访问的是一级路由时,默认的二级路由组件可以得到渲染,只需要在二级路由的位置去掉path,并设置index属性为true即可。
6.ReactRouter的404路由配置
当浏览器输入url的路径在整个路由配置中都找不到对应的path,为了用户体验,可以使用404兜底组件进行。1.准备一个404组件,2.在路由表的末尾以*号作为路由path配置路由
const router = createBrowserRouter([{path:'/login',element:<Login/>},{path:'/index',element:<App/>,children:[{path:"ArticleManage",element:<ArticleManage/>}]},{path:'*',element:<NotFound/>},
])
7.ReactRouter有两种路由模式,history模式和hash模式,这个和vue是一样的。分别可以通过createBrowerRouter和createHashRouter函数来进行创建