因个人工作原因,在2023年学起了React + TS 这个 “前端大佬” “高阶玩家” 标配的技术栈,一套学习下来个人总结就是:React真特么难用!传染病式的渲染逻辑是真让人难受!
如何解决React组件抽风式的刷新问题,小编使用解释和源码示例的方式讲解一下
- // 子组件
- // 若不适用 memo API,父组件每次跟新 time 时,子组件都会重新渲染,输出 'List 被渲染'
- const List = memo((props:{
- list:Array<string>
- })=>{
- console.log('List 被渲染')
- return (
- <>
- <ol>
- {
- props?.list.map(item=>{
- return ( <li key={item}>{item}li> )
- })
- }
- ol>
- >
- )
- })
-
- export default () => {
- const [ time,setTime ] = useState(0);
- const [ list,setList ] = useState<string[]>([]);
-
- useEffect(()=>{
- setTimeout(() => {
- setTime(time+1);
- }, 1000);
- },[time])
-
- return (
- <>
- <h1>页面浏览时长:{time}秒h1>
- <List list={list} />
- >
- );
- };
- // 子组件
- const List = memo((props:{
- oddOrEven?:string,
- list:Array<string>
- })=>{
- console.log('List 被渲染')
- return (
- <>
- <h3>列表长度为:{props.oddOrEven}h3>
- <ol>
- {
- props?.list.map(item=>{
- return ( <li key={item}>{item}li> )
- })
- }
- ol>
- >
- )
- })
-
- export default () => {
- const [ time,setTime ] = useState(0);
- const [ list,setList ] = useState<string[]>([]);
-
- useEffect(()=>{
- setTimeout(() => {
- setTime(time+1);
- }, 1000);
- },[time])
-
-
- // 奇数或偶数
- // 当传递给子组件的值是通过函数返回的情况下,需要使用 useMemo Hook
- const oddOrEven = useMemo(()=>{
- return (list.length % 2 === 0 ? '偶数':'奇数');
- },[list])
-
-
- return (
- <>
- <h1>页面浏览时长:{time}秒h1>
- <List list={list} oddOrEven={oddOrEven} />
- >
- );
- };
- // 子组件
- const List = memo((props:{
- list:Array<number>,
- click:(number:any)=>void
- })=>{
- console.log('List 被渲染')
- return (
- <>
- <button type='button' onClick={()=>{
- const t = new Date().getTime();
- props.click(t);
- }}>添加button>
- <ol>
- {
- props?.list.map(item=>{
- return ( <li key={item}>{item}li> )
- })
- }
- ol>
- >
- )
- })
-
- export default () => {
- const [ time,setTime ] = useState(0);
- const [ list,setList ] = useState<number[]>([]);
-
- useEffect(()=>{
- setTimeout(() => {
- setTime(time+1);
- }, 1000);
- },[time])
-
- // 若传递给子组件的属性有函数,需要使用 useCallback Hook,否则子组件发疯式的重新渲染
- const handleClick = useCallback((time:number)=>{
- setList([
- ...list,
- time
- ])
- },[list])
-
- return (
- <>
- <h1>页面浏览时长:{time}秒h1>
- <List list={list} click={ handleClick } />
- >
- );
- };
答:
- // 子组件
- const Card = (props:any)=>{
- console.log('渲染组件 Card')
- return (
- <div style={{border:'#ccc solid 1px'}}>
- <div>
- {props.head}
- div>
- <div>
- <h2>card-bodyh2>
- div>
- div>
- )
- }
-
- // 孙组件
- const CardHead = ({count}:{count:number})=>{
- console.log('渲染组件 Card-Head')
- return (
- <h1>card-header -- 点击统计:{count}h1>
- )
- }
-
- export default () => {
- const [ time,setTime ] = useState(0);
- const [ countClick, setCountClick ] = useState(0);
-
- const cardHeader = useMemo(()=>{
- return <CardHead count={countClick} />
- },[countClick])
-
- useEffect(()=>{
- setTimeout(() => {
- setTime(time+1);
- }, 1000);
- },[time])
-
- return (
- <>
- <h1>页面浏览时长:{time}秒h1>
- <button type='button' onClick={()=>{
- setCountClick(countClick+1)
- }}>点击统计button>
- <Card head={cardHeader} />
- >
- );
- };
最后唠叨几句:我每次看完React文档后,我觉得我学会了,过一周后我发现自己还没学会。这玩意坑到底还有多少,我醉了!我在知乎上看到过有个人说“这世界上没有人能真正会用 useEffect”,想深入了解学习可以阅读 《useEffect 完整指南》,看完文章真让人上头。
我讨厌 React!
作者:黄河爱浪
本文原创,著作权归作者所有,转载请注明原链接及出处