【小知识:命令输入rm -rf(window用rm *),作用无提示地递归删除当前目录下所有文件,并且不能恢复】
#### useState
```jsx
import React, { useState } from "react";
export default function Name() {
//Hook只能用在函数中的最顶层
const [msg, setmsg] = useState("你好世界");
return (
<div>
<h1>{msg}</h1>
<button onClick={() => setmsg("Hello World")}>点击改名</button>
</div>
);
}
```
#### useEffect
| function式组件 | class式组件 |
| ------------------------------------------------------------ | --------------------------------------- |
| useEffect(()=>{//生命周期方法1=组件挂载+任意数据改变 }) | componentDidMount+componentDidUpdate |
| useEffect(()=>{//生命周期方法2=组件挂载+依赖的数据改变},[count,age]) | componentDidMount+componentDidUpdate |
| useEffect(()=>{//生命周期方法3=组件挂载},[]) | componentDidMount |
| useEffect(()=>{return ()=>{//生命周期方法4=任意数据改变+组件卸载}}) | componentDidUpdate+componentWillUnmount |
| useEffect(()=>{return ()=>{//生命周期方法5=依赖的数据改变+组件卸载}},[count,age]) | componentDidUpdate+componentWillUnmount |
| useEffect(()=>{return ()=>{//生命周期方法5=组件卸载}},[]) | componentWillUnmount |
//卸载阶段一般用来处理脏数据,或者垃圾回收
#### createContext
```jsx
import React, { createContext, useState } from "react";
const NameContext = createContext();
function Child() {
return (
<NameContext.Consumer>
{(say) => {
return <h1>{say}</h1>;
}}
</NameContext.Consumer>
);
}
function Father() {
return <Child />;
}
//顶级组件
export default function Name() {
const [msg, setmsg] = useState("念想");
return (
<NameContext.Provider value={msg}>
<Father />;
</NameContext.Provider>
);
}
```
```jsx
import React, { createContext, useState } from "react";
const NameContext = createContext();
function Child() {
return (
<NameContext.Consumer>
{({ msg, setmsg }) => {
return (
<>
<h1>{msg}</h1>
<button onClick={() => setmsg("永不消散")}>点击修改</button>
</>
);
}}
</NameContext.Consumer>
);
}
function Father() {
return <Child />;
}
//顶级组件
export default function Name() {
const [msg, setmsg] = useState("念想");
return (
<NameContext.Provider value={{ msg, setmsg }}>
<Father />;
</NameContext.Provider>
);
}
```
#### useContext
```jsx
import React, { createContext, useContext, useState } from "react";
const NameContext = createContext();
function Child() {
const { msg, setmsg } = useContext(NameContext);
return (
<>
<h1>{msg}</h1>
<button onClick={() => setmsg("永不消散")}>点击修改</button>
</>
);
}
function Father() {
return <Child />;
}
//顶级组件
export default function Name() {
const [msg, setmsg] = useState("这份念想");
return (
<NameContext.Provider value={{ msg, setmsg }}>
<Father />;
</NameContext.Provider>
);
}
```
#### 受控组件
所谓的受控组件就是表单元素的value需要通过state(或setState)来定义
```jsx
import React, { useRef, useState } from "react";
//受控组件
export default function Name() {
const [msg, setmsg] = useState("asd");
const num = (e) => {
console.log(e.target.value);
setmsg(e.target.value);
};
return (
<>
<input onChange={num} value={msg} />
<button>查询</button>
</>
);
}
```
#### 非受控组件
非受控组件意味着表单元素的value无法通过state获取,只能使用ref(或useref)来获取
```jsx
import React, { useRef, useState } from "react";
//非受控组件
export default function Name() {
const msg = useRef(null);
return (
<>
<input ref={msg} />
<button
onClick={() => {
console.log(msg.current.value);
}}
>
查询
</button>
</>
);
}
```
#### memo(防止子组件被重复触发影响性能)
问题说明:代码如下,每次父组件更新都会导致子组件被迫更新,这很影响性能
```jsx
import React, { useState } from "react";
const Child = () => {
console.log("子组件被触发了");
return <h1>子组件</h1>;
};
export default function Name() {
const [num, setnum] = useState(0);
return (
<>
<div>{num}</div>
<button onClick={() => setnum(num + 1)}>点击加一</button>
<Child></Child>
</>
);
}
```
解决方法:使用memo,防止代码块被重复触发
```jsx
import React, { memo, useState } from "react";
const Child = memo(() => {
console.log("子组件被触发了");
return <h1>子组件</h1>;
});
export default function Name() {
const [num, setnum] = useState(0);
return (
<>
<div>{num}</div>
<button onClick={() => setnum(num + 1)}>点击加一</button>
<Child></Child>
</>
);
}
```
#### useCallback
meno有个缺点,如果子组件是纯静态的,那么父组件更新,被memo包裹的子组件将不会被重复渲染,但是如果子组件是动态的,依然会被重复渲染,这个时候就需要结合useCallback,让子组件不会被重复更新(写法上类似于useEffect)
```jsx
import React, { memo, useState, useCallback } from "react";
const Child = memo((props) => {
const { add } = props;
console.log("子组件被触发了");
return (
<>
<h1>子组件</h1>
<button onClick={add}>子组件点击加一</button>
</>
);
});
export default function Name() {
const [num, setnum] = useState(0);
const add = useCallback(() => {
/*
setNum(newValue)使用新值强行覆盖初始值
setNum((num)=>num+1)不断使用新值覆盖旧值
*/
setnum((num) => num + 1);
}, []);
return (
<>
<div>{num}</div>
<button onClick={() => setnum(num + 1)}>点击加一</button>
<Child add={add}></Child>
</>
);
}
```
#### useMemo
作用和上述useCallback相同,只不过写法上有区别
```jsx
import React, { memo, useState, useMemo } from "react";
const Child = memo((props) => {
const { add } = props;
console.log("子组件被触发了");
return (
<>
<h1>子组件</h1>
<button onClick={add}>子组件点击加一</button>
</>
);
});
export default function Name() {
const [num, setnum] = useState(0);
//函数中返回函数称为高阶函数
const add = useMemo(() => {
/*
setNum(newValue)使用新值强行覆盖初始值
setNum((num)=>num+1)不断使用新值覆盖旧值
*/
return () => setnum((num) => num + 1);
}, []);
return (
<>
<div>{num}</div>
<button onClick={() => setnum(num + 1)}>点击加一</button>
<Child add={add}></Child>
</>
);
}
```
#### React Redux状态管理工具
```jsx
//'./store/index.js'
//项目入口文件
import reducer from "./reducer";
import { createStore } from "redux";
const store = createStore(reducer);
export default store;
```
```jsx
//'./store/reducer.js'
//创建初始状态
const defaultState = {
num: 1,
};
//并导出一个函数
export default (state = defaultState,action) => {
let newState=JSON.parse(JSON.stringify(state))
// if(action.type=="addNum"){
// newState.num+=action.value
// }
switch (action.type) {
case "addNum":
newState.num += action.value;
break;
default:
break;
}
return newState;
};
```
```jsx
//index.js
import ReactDOM from "react-dom/client";
import App from './App'
import {Provider} from 'react-redux'
import store from './store'
ReactDOM.createRoot(root).render(
<Provider store={store}>
<App/>
</Provider>Provider>
)
```
```jsx
import React from "react";
import { connect } from "react-redux";
function Test(props) {
return
<>
<div>{props.num}</div>
<button onClick={()=>props.leijia()}>累加</button>
</>
}
//状态映射:将reducer中的state映射成props,让开发者可以在组件中使用props.num去调用state中的num
const mapStateToProps = (state) => {
return {
num: state.num,
};
};
//事件派发映射:将reducer中的事件映射成props,让开发者可以在组件中使用props.leijia()去实现num的累加
const mapDispatchToProps=(dispatch)=>{
return {
leijia(){
const action={type:"addNum",value:2}
dispatch(action)
}
}
}
//export default connect(state映射,dispatch映射)(当前组件名称);
//映射其实就是函数
//connect是一个高阶函数
export default connect(mapStateToProps,mapDispatchToProps)(Test);
```