创建项目
1 2 3 4 5 6 7 8 9 10 11
| npx create-react-app xxx
npm i axios
npm install @reduxjs/toolkit react-redux
........ 更多配置自行构建
|
注意:在项目中需要挂载。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import React from 'react'; import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { HashRouter, BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( <HashRouter> <React.StrictMode> <App /> </React.StrictMode> </HashRouter> );
|
注意: React.StrictMode 开发状态下的严格模式
StrictMode 是一个用来检查项目中潜在问题的工具。StrictMode 不会渲染任何可见的 UI,它为其后代元素触发额外的检查和警告。
1 2 3 4 5 6 7 8 9
| 严格模式检查仅在开发模式下运行;它们不会影响生产构建。
StrictMode 目前有助于:
1、识别不安全的生命周期; 2、关于使用过时字符串 ref API 的警告; 3、关于使用废弃的 findDOMNode 方法的警告; 4、检测意外的副作用; 5、检测过时的 context API。
|
路由配置
Routes , Route , Outlet 路由匹配
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
| <Routes> <Route path="/" element={<Home></Home>}></Route> {} <Route path="/" render={ ()=> <Redirect to="/home"/>}></Route> <Route path="/home" component={Home}></Route> */}
{} <Route path="about" element={<About />} caseSensitive={true}></Route>
{} <Route path='/news' element={<News />}> {} {} <Route index element={<div>默认新闻</div>}></Route> <Route path='china' element={<div>中国新闻</div>}> {/* 三级路由 */} </Route> <Route path='world' element={<div>世界新闻</div>}></Route> </Route> <Route path='/useEffect' element={<UseEffect></UseEffect>}></Route> </Routes>
<NavLink to='/news' end>默认</NavLink> <NavLink to='/news/china'>中国</NavLink> <NavLink to='/news/world'>世界</NavLink>
|
路由传参 useParams,useSearchParams,useLocation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| params 传参 {} <Route path='/class/:id' element={<ClassItem></ClassItem>}></Route>
const {id} = useParams() console.log(id);
let [query] = useSearchParams() console.log(query.get('hh'));
let location = useLocation() console.log(location);
|
导航路由跳转 Link , NavLink ,
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
| import { Link, NavLink, useNavigate } from "react-router-dom"
<Link to='/class/124'><li>124期</li></Link> <NavLink to='/class/124'>世界</NavLink>
let navigate = useNavigate();
let ToDetail = (id) => { console.log(id); router(`/class/${id}?type=前端&age=5&type=后端`, {state: {a: 1, b: 2}}); }
1.window 方法 window.history.back() 2.导入history库(由react-router团队开发,为react-router依赖库)
yarn add history
import { createHashHistory } from 'history' const history = createHashHistory({window})
const backHandle = ()=>{ history.go(-1) }
|
路由页面 异步加载,按需加载 进入页面Loading 加载中效果
第一种方法 异步加载 lazy懒惰 懒加载,按需加载 需要搭配Suspense
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import Loading from './views/Loading.jsx';
const UseContext = React.lazy(() => import('./views/UseContext.jsx'));
<Route path='/useContext' element={ <Suspense fallback={<Loading></Loading>}> <UseContext></UseContext> </Suspense> }> </Route>
|
第二种方法 异步加载 可以不使用Suspense 需要安装依赖@loadable/component
1 2 3 4 5 6 7 8 9 10
| npm install @loadable/component -S
import loadable from '@loadable/component'; const UseContext = loadable(() => import('./views/UseContext.jsx'), { fallback: <Loading></Loading> })
<Route path='/useContext' element={<UseContext></UseContext>}></Route>
|
1. 创建 store 仓库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| npm install @reduxjs/toolkit react-redux
import { configureStore } from '@reduxjs/toolkit' import productReducer from './product'
export default configureStore({ reducer: { product: productReducer } })
|
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import { createSlice } from '@reduxjs/toolkit'
let product= createSlice({ name: 'product', initialState: { count: 1, list: ['iphone18 pro max 1TB 暗夜紫'] }, reducers: { changCount(state, data) { console.log(state.count, state.list[0], data); state.count = state.count + data.payload.n; }, changeList(state, {payload}) { state.list = payload; } } })
export default product.reducer;
export let {changCount, changeList} = product.actions;
export let getDataSync = playload => dispatch => { setTimeout(() => { let arr = ['小米13pro', '华为mate70 保时捷版', '三星嘎拉克斯22+']; dispatch(changeList(arr)); }, 2000); }
export let getDataSync = playload => { return dispatch => { } }
|
3.导入组件内访问store内数据,并调用方法进行更新操作
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
| import { useSelector, useDispatch } from 'react-redux'; import { changCount, getDataSync } from '../store/product' import { useEffect } from 'react';
export default function() {
let {count, list} = useSelector(state => state.product); console.log(count, list);
let dispatch= useDispatch();
let handleChangeCount = () => { dispatch(changCount({n: 10})) }
useEffect(() => { dispatch(getDataSync()); }, []);
return <div> <h1>Home页面</h1> {/* <p>{product.count}--{product.list}</p> */} <p>{count}--{list}</p> <button onClick={handleChangeCount}>更改count</button> </div> }
|
请求封装 axios
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
| npm i axios
import axios from "axios";
export function http(config) { let instance = axios.create({ baseURL: "https://www.baidu.com", timeout: 3000, });
}
import {http} from './index'
export function GetHomeData(animal) { return http({ url: `/xx/xxxx/xxxx/xxxxxxxx`, }) }
import { GetHomeData, GetLikeData } from '../../newwork/getData'
GetHomeData(catOrdog).then(res => { console.log(res.data); })
|
useState , useRef , useEffect useContent 总线 插槽
useState
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import { useState } from 'react';
let [title,settitle] = useState('哈哈哈')
settitle('略略略')
let arr = [1,2,3,4,5,6] let [arr1,setarr1] = useState(arr)
let newarr = [4,5,6,7,8] setarr1(newarr)
setarr1([...newarr])
|
useRef
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import { useEffect, useRef, useState } from "react"
let myref = useRef(''); console.log(myref.current);
<h3 ref={myref}>我是h3</h3>
useEffect(() => { console.log('useEffect,视图渲染结束之后才执行useEffect,相当于vue中的mounted'); console.log(myref.current); }, [])
|
useEffect
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 { useEffect, useRef, useState } from "react"
let [count, setCount] = useState(0); let changeCount = () => { setCount(10); console.log(count); } useEffect(() => { console.log(count); }, [count])
useEffect(() => {
return () => { console.log('销毁了'); } }, [])
useEffect是一个React Hook,用于在组件渲染时执行副作用操作,类似于类组件中的生命周期函数。 useEffect的作用是在组件渲染完成后执行一些操作,比如发送网络请求、订阅事件、更新DOM等。 useEffect接收两个参数,第一个参数是一个函数,用于执行副作用操作,第二个参数是一个数组,用于指定依赖项,当依赖项发生变化时,useEffect会重新执行。 useEffect的执行顺序是在组件渲染完成后执行,如果指定了依赖项,当依赖项发生变化时,useEffect会先执行清除操作,然后再执行副作用操作。
|
useContent 总线传值 插槽传递
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 44 45 46 47
| 1.在src 下创建 mooudle 文件夹 创建bus.js 文件
import React from 'react';
let myContext = React.createContext();
export default myContext;
2. 在要使用Context 传值的组件中导入使用 <MyContext.Provider></MyContext.Provider> 中包裹要传给的组件 import MyContext from '../modules/bus.js';
import Child1 from '../components/Child1.jsx'; import Child2 from '../components/Child2.jsx';
export default function () { let person = { name: 'ikun', age: 10, }
return <div> <h3>演示useContext</h3>
{/* 提供数据 */} <MyContext.Provider value={person}> {/* 插槽第一种写法 自定义属性 在child1里面 props.slot接收 */} <Child1 slot={<img width="100px" src='https://img1.baidu.com/it/u=1960110688,1786190632&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281' />}></Child1> <Child1 slot={<img width="100px" src='https://img1.baidu.com/it/u=1472391233,99561733&fm=253&fmt=auto&app=120&f=JPEG?w=889&h=500' />}></Child1>
{/* 插槽第二种写法 内容区传递的 在child2里面 props.children接收 */} <Child2> <h1>我是child2的第一个h1</h1> <h1>我是child2的第二个h1</h1> <h1>我是child2的第三个h1</h1> </Child2> </MyContext.Provider> </div> }
3.接收使用 Context 总线上的值
import myContext from "../modules/bus"; import { useContext } from "react";
let value = useContext(myContext); console.log(value);
|