一、脚手架创建项目 create-react-app
//局部创建
局部创建create-react-app
yarn init -y
yarn add -D create-react-app
创建项目
npx create-react-app react-demo1
//全局创建
npm install -g create-react-app
create-react-app 项目名
二、css模块化
在react中可以将css模块化,例如home.jsx页面的css样式可以新建一个home.module.css文件里面写样式,例如:
.wrap{
width:100px;
height:100px;
background:#ccc;
}
.active{
color:#999;
}
使用:在组件中引入
import styles from './home.module.css'
function App(){
return (
)
}
三、hooks
1.useState() 维护函数内的状态
使用:
import {useState} from 'react'
function App(){
let [id,setId] = useState(0);
return (
{id}
)
}
手写setsState
function useState(iniState)(){
let state = iniState
const setState = newState=>{
state = newstate;
render();
}
return [state,setState]
}
2.useCallback
import { useState,useEffect } from "react";
function App() {
let [state,setState] = useState(0);
useEffect(()=>{
console.log('我被触发了·')
},[money])
const test = ()=>{
console.log(state)
console.log('函数test被执行了',state)
}
return (
Hooks
{state}
{money}
);
}
export default App;
在这里外部state点击改变数据后,执行test函数每次test都可以拿到最新的值,说明每次test函数都是最新的函数,会浪费性能,这个时候useCallback的作用就是缓存函数,依赖更新函数才会更新,传入空数组[],就不会更新函数console.log(state)这个时候就打印的是初始值,数组中传入了变量,就会根据变量的改变来更新函数,如果不传递,不缓存每次都更新。
import { useState,useEffect,useCallback } from "react";
function App() {
let [state,setState] = useState(0);
useEffect(()=>{
console.log('我被触发了·')
},[money])
useCallback(()=>{
console.log(state)
console.log('函数test被执行了',state)
},[])
return (
Hooks
{state}
{money}
);
}
export default App;
3.useEffect() effect副作用,与渲染无关的行为都是副作用
是生命周期的集合(componentDidMount,componmentDidUpdate componmentWillUnmount)
使用:
useEffect(()=>{},[]);
接受两个参数,第一个是回调函数,第二个是一个数组,如果空数组不执行回调,如果传入变量,依赖的变量改变回调就会执行,什么都不传只有数据有更新回调就会执行
useEffect(()=>{
console.log('我被触发了·传入money')
},[money])
useEffect(()=>{
console.log('我被触发了·传入空数组')
},[])
useEffect(()=>{
console.log('我被触发了·啥都不传')
},)
在useEffect中也可以清除定时器,监听操作(清除副作用)
清除定时器
useEffect(()=>{
return ()=>{
在这里清除
}
})
4.useMemo();计算结果并根据依赖缓存使用方法和useEffect类似
5.useContext()
首先,我们需要创建一个Context对象,用于共享数据:
// 创建一个Context对象
const MyContext = React.createContext();
// 创建一个Provider组件,用于提供共享数据
const MyProvider = ({ children }) => {
const sharedData = "Hello, useContext!";
return (
{children}
);
};
然后,在需要使用共享数据的组件中,使用useContext来获取共享数据:
// 使用共享数据的组件
const MyComponent = () => {
// 使用useContext获取共享数据
const sharedData = React.useContext(MyContext);
return {sharedData};
};
最后,在应用的根组件中,使用MyProvider组件包裹需要使用共享数据的组件:
// 应用的根组件
const App = () => {
return (
);
};
这样,MyComponent组件就可以通过useContext获取到共享数据,并在渲染时显示出来。
注意:使用useContext时,需要确保Provider组件包裹了需要使用共享数据的组件,否则无法获取到共享数据。
5.useRef()
const divRef = useRef(null);
获取子组件dom
import React, { useRef } from 'react';
const ParentComponent = () => {
const childRef = useRef(null);
const handleClick = () => {
// 通过ref.current获取子组件的DOM
console.log(childRef.current);
};
return (
);
};
const ChildComponent = React.forwardRef((props, ref) => {
return 子组件;
});
export default ParentComponent;
四、高阶组件
接受一个组件,返回一个组件
import React from 'react';
// 高阶组件
const withLoading = (WrappedComponent) => {
return class extends React.Component {
state = {
isLoading: true
};
componentDidMount() {
// 模拟异步加载数据
setTimeout(() => {
this.setState({ isLoading: false });
}, 2000);
}
render() {
return this.state.isLoading ? (
Loading...
) : (
);
}
};
};
// 普通组件
const MyComponent = (props) => {
return 内容加载完成;
};
// 使用高阶组件包装普通组件
const MyComponentWithLoading = withLoading(MyComponent);
const App = () => {
return (
);
};
export default App;
五、react路由
react路由库分为
react-router-dom (浏览器)
react-router-native(app)
useParams()获取url的参数
如果URL为/users/123
,则可以使用useParams()方法获取到参数123:
import { useParams } from "react-router-dom";
function User() {
const { id } = useParams();
return (
User ID: {id}
);
}
useLocation()用于获取当前url的信息
例如,如果当前URL为/users?name=John#section1
,则可以使用useLocation()方法获取到以下信息:
import { useLocation } from "react-router-dom";
function MyComponent() {
const location = useLocation();
console.log(location.pathname); // 输出:/users
console.log(location.search); // 输出:?name=John
console.log(location.hash); // 输出:#section1
return (
Current URL: {location.pathname}
);
}
useNavigate()提供了导航相关的方法,类似于useHistory()
navigate对象包含了以下方法:
例如,可以在点击按钮时使用navigate()方法进行导航:
import { useNavigate } from "react-router-dom";
function MyComponent() {
const navigate = useNavigate();
const handleClick = () => {
navigate("/new-page");
};
return (
);
}
useHistory(),用于管理历史记录和导航
例如,可以在点击按钮时使用push()方法进行导航:
import { useHistory } from "react-router-dom";
function MyComponent() {
const history = useHistory();
const handleClick = () => {
history.push("/new-page");
};
return (
);
}
useHistory(),useLocation(),useParams(),useNavigate()方法只能在被Route组件包裹的组件中使用。如果在没有被Route组件包裹的组件中使用这些方法,将会抛出错误。
路由的动态生成
import {useRoutes} from 'react'
const routes = [
{path:'/',element:},
{path:'/basic',element: },
{path:'/basic/:id',element: },
//嵌套路由
{
path:'/layout',element: ,
children:[
path:'movie',element:
]
}
]
const getRoutes = ()=>{
const elements = useRoutes(routes);
//useRoutes必须要在名称为getRoutes的方法中
return elements ;
}
使用
memo()高阶函数里面传入一个组件,缓存组件(父组件每次重新渲染,子组件就会更新,memo高阶组件传入子组件,只有当props数据改变的时候子组件才会更新)