赞
踩
class组件——功能全、东西多;麻烦
函数组件——功能弱、东西少;方便
函数组件:
1.状态——能变的、重新渲染
class √
fc × hook
2.this——当前实例
class √
fc ×
3.ref——引用
class √
fc × hook
4.方法
class √
fc × hook
hook:一套工具函数的集合——增强fc的功能
函数组件专用的
hook:一套工具函数的集合——增强fc的功能
hook!=函数组件
注意第四点,useState也可以传入一个函数,这个函数只会被调用一次,用在初始值是动态值的情况。
例如:
在上面代码中 const propsCount = props.count || 0 是不合理的,因为每次setState都会执行这行代码,而这行代码的意图是在初始化的时候执行,因此我们需要在useState的参数里放入一个函数。
改进写法:
// App.jsx
<Content
// key={tabValue} 重置key与不重置key对useState的影响
tabValue={tabValue}
/>
// Content.jsx
import { getDealColumns, getUVColumns } from './config';
function Content(props) {
if (tabValue === 'Trade') {
getTableColumns = getDealColumns;
} else if (tabValue === 'UVIndex') {
getTableColumns = getUVColumns;
}
const [tableColumns, setTableColumns] = useState(getTableColumns());
console.log(tableColumns); // 切换tabs,如果没有重置key,这里的tableColumns不会变
}
使用useState初始的变量可以等价于为在class组件中的constructor里定义的state,如果组件没有重置key,那么useState初始的变量不会改变,重置了key,才会改变。
因此,状态尽量全部扔到Redux里。
即:在一个事件里触发多次setState,只会触发一次render
import React, {useState} from 'react'; export default function CounterHook() { const [count, setCount] = useState(() => 10); console.log("CounterHook渲染"); function handleBtnClick() { // 下面这种只会加10 // setCount(count + 10); // setCount(count + 10); // setCount(count + 10); // setCount(count + 10); // 下面这种会加40 setCount((prevCount) => prevCount + 10); setCount((prevCount) => prevCount + 10); setCount((prevCount) => prevCount + 10); setCount((prevCount) => prevCount + 10); } return ( <div> <h2>当前计数: {count}</h2> <button onClick={handleBtnClick}>+10</button> </div> ) }
通过import() 动态导入组件:
import React, { FC, useEffect, useState } from 'react'; import Test from './Test1'; console.log(11, Test) type Props = { name: string; age: number; }; const App: FC<Props> = props => { const [count, setCount] = useState(0); const [Comp, setComp] = useState(() => { return () => { return <div>11</div> } }); useEffect(() => {}); const handleClick = async() => { setCount(count + 1); const content = () => import('./Test1'); const { default: Comp } = await content(); // 对于import进来的组件,在setState的时候需要仍然是一个函数,因为前面useState类型的时候就定义了是一个函数,所以必须setState的时候是同样类型的 setComp(() => Comp) }; return ( <div> <h1>hello</h1> <div> {props.name} {props.age} </div> <div> <button onClick={() => handleClick()}>按钮{count}</button> </div> <Comp /> </div> ); }; export default App;
useState: https://zh-hans.reactjs.org/docs/hooks-reference.html#usestate
2.影响——useEffect
把操作推迟到渲染完成,操作的结果会在下次渲染体现
模拟一部分生存周期函数
3.引用——useRef/forwardRef
问题:如何在父组件中引用子组件的某个元素?
这时候就用到了forwardRef
参考链接:forwardRef
4.上下文——useContext
theme主题
5.数据——useReducer
useState(初始值) => [值, function set];
this.state={
x: ?
}
this.state.a=99; //×
this.setState({ //√
a: 99
});
this.setState
react的状态——在渲染的过程中,保持不变的;所有的修改存着,等到渲染完成之后一块改、并且触发重新渲染
性能——理论上会降低(极少),极大提升程序稳定性
StrictMode——严格模式
1.找到所有的依赖项
2.渲染
只存在于development模式,打包以后就没了
hook过程
伪代码如下:
阅读源码,不能逐行去抠,而是弄懂里面的原理;
hook1+action=>hook2
hook2+action=>hook3
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。