useState
* React主要是通过setState, useState方法来更新状态, 状态更新之后, 组件也会重新渲染
1. useState 有2种初始化的方式
第一种 useState(值)
第二种 useState(() => {
写逻辑
return 值
})
2. useState 全都是异步的
修改完以后 如果想立刻获取上一次的值 可以使用 useState的 set方法 接收一个回调函数
setX(pre => {
// pre 就是上一的值
return pre
})
3. useState 为什么要做成异步的?
如果是同步, 比如我连续调用5次, 页面就会刷新5次, 浪费性能, 所以把它做成异步的, 对同一个值进行多次 setState
setState的批量更新策略会对其进行覆盖 取最后一次的执行结果, 如果是同时 setState 多个不同的值, 在更新时会对其进行合并批量更新
// useState 使用方法
export default () => {
// 异步
const [x1, setX1] = useState(1)
const [x2, setX2] = useState(() => {
// ajax
if (true) {
return 3
} else {
return 2
}
})
const onClick = opt => {
// 异步 (等一小会)
setX1(x1 + 1)
// prevState 上一次的值
setX1(prevState => {
console.log(prevState, 'prevState');
// return 出去的值就是 x1 的值
return prevState
})
console.log(x1, 'x1');
}
return (
<div>
<h1>{x1}</h1>
<Button onClick={onClick}>改变x1</Button>
</div>
)
};
useEffect
- useEffect 可以模拟哪些生命周期
- componentDidMount // 加载完成的
- componentDidUpdate // 更新阶段
- componentWillUnmount // 卸载阶段
// * 加载阶段
useEffect(() => {
// setInterval, setTimeout 会形成闭包, 会保存 time 的复制值, 该值与外面的 time
// 不是同一个值
setInterval(() => {
setTime(time - 1)
// 始终输出 3
console.log(time, 'xxx');
}, 1000)
}, [])
// * 更新阶段
useEffect(() => {
// setInterval, setTimeout 会形成闭包, 会保存 time 的复制值, 该值与外面的 time
// 不是同一个值
setInterval(() => {
setTime(time - 1)
// 始终输出 3
console.log(time, 'xxx');
}, 1000)
}, [data])
// * 卸载阶段
useEffect(() => {
return ()=>{
}
}, [data])
useRef 与 createRef的区别
- useRef
在页面渲染时只执行一次, 有初始值, 可以用于保存上一次的值, 可以获取dom节点, useRef在每次渲染时返回同一个ref对象, 只有current读写- createRef
每次组件渲染都会执行, 没有初始值, 主要用于class组建中创建refs
// 1. createRef 只要组件重新渲染 createRef 就会重新重新执行
export default () => {
const [x1, setX1] = useState(() => {
return 1
})
// 特性: useRef 页面渲染的时候只执行一次
// 特性: 只有 current 读写
// 返回值: { current: undefined } 内存地址 abc
// 作用1. 获取DOM
// 作用2. 存储上一次的值
const ref = useRef()
const ref2 = createRef()
const onClick = opt => {
// ref.current === 1
ref.current = x1
ref2.current = x1
// 异步
setX1(x1 + 1)
}
return (
<div>
<h1>{x1}</h1>
<h1 ref={ref}>小花</h1>
<h1 ref={ref2}>小蓝</h1>
<Button onClick={onClick}>改变x1</Button>
</div>
)
}
useMemo
- useMemo 有两个参数,一个回调函数,一个依赖,回调函数里必须有返回值
- useMemo 的特性是缓存return出来的值,如果依赖为空 useMemo缓存的值永远不会改变,如果依赖改变,缓存的值会重新发生改变
- useMemo 主要用来缓存计算结果的值
/*
特性:
1. 有一个返回值 回调函数里 retrun 的值
2. useMemo 立刻执行的
const fn = useMemo(() => {
return 123
return () => {
}
}, [])
*/
export default connect(({ loading }) => {
return {
loading: !!loading.effects['upload/fetch'],
}
})(UseCallback)
function UseCallback (props) {
const { dispatch, loading } = props
const [form] = Form.useForm()
const [fileList, setFileList] = useState([])
const [x, setX] = useState(20000)
const [y, setY] = useState(20000)
// 第一次刷新 x === 20000
// 第二次 x === 20001
const x1 = useMemo(() => {
console.log('我执行了');
let sum = 0
for (let i = 0; i < x; i++) {
sum += i
}
return sum
}, [x])
return (
<div style={{background: '#000'}}>
<h1>x: {x1}</h1>
<h1>y: {y}</h1>
<h1 onClick={() => setX(x + 1)}>x: {x}</h1>
<h1 onClick={() => setY(y + 1)}>y: {y}</h1>
</div>
)
}
useCallback
- useCallback 有两个参数, 第一个参数是一个回调函数, 第二个参数是一个依赖
- useCallback 缓存一个函数, 依赖为空的时候,缓存的函数不会改变,依赖改变,缓存的函数就跟着改变
- useCallback 是 useMemo 语法糖,一个缓存函数,一个缓存值
- useCallback 返回函数而不调用 useMemo 调用函数并且返回结果
/*
用途: 父组件刷新 子组件不刷新
返回一个新函数 如果依赖是空 新函数的指针永远不变
依赖是空 useCallback 永远只执行一次
const fn = useCallback(() => {
}, [])
// 如果依赖改变了 重新返回指针变了的新函数
const fn = useCallback(() => {
}, [x])
*/
export default function UseCallback () {
const [x, setX] = useState(0)
// console.log('我是父组件,我执行了');
// fn 保存的 123指针 -> () => console.log(1)
// 第一次渲染 fn 123
// 第二次 直接把 123 指针 给 fn
// 第三次 直接把 123 指针 给 fn
const fn = useCallback(() => {
// console.log(1)
}, [])
return (
<>
<h1 onClick={() => setX(x + 1)}>x: {x}</h1>
<QuseCallBack
fn={fn} // 123
/>
</>
)
}
useContext
useContext 自定义默认值
useContext 父子组件传值
useContext 方法接收一个 context 对象(
React.createContext的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的<MyContext.Provider>的valueprop 决定。
当组件上层最近的
<MyContext.Provider>更新时,该 Hook 会触发重渲染,并使用最新传递给MyContextprovider 的 contextvalue值。即使祖先使用React.memo或shouldComponentUpdate,也会在组件本身使用useContext时重新渲染。
可以理解为,
useContext(MyContext)相当于 class 组件中的static contextType = MyContext或者<MyContext.Consumer>。
useContext(MyContext)只是让你能够读取 context 的值以及订阅 context 的变化。你仍然需要在上层组件树中使用<MyContext.Provider>来为下层组件提供 context。
Hoc高阶组件
function Hoc(WrappedComponent) {
return () => {
const [xy, setXY] = useState({
x: 0,
y: 0,
});
useEffect(() => {
const fun = ({ clientX, clientY }) => {
setXY({
x: clientX,
y: clientY,
});
};
// DOM2
document.addEventListener('mousemove', fun);
return () => {
document.removeEventListener('mousemove', fun);
};
}, []);
return <WrappedComponent xy={xy} />;
};
}
function Home(props) {
const { xy } = props;
return (
<div>
<h1>
{xy.x}--{xy.y}
</h1>
</div>
);
}
export default Hoc(Home);
还没写完!! 自己总结的 有问题的及时联系我删改哦~ 谢谢!