React+TypeScript+Hooks+Umi+Dev+Ant Design(笔记篇)

11 篇文章 0 订阅

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

项目结构文件

  1. const.ts
/** select下拉框 */
export const option = [
  { label: '选项1', key: '1' },
  { label: '选项2', key: '2' },
  { label: '选项3', key: '3' },
]
  1. service.ts
import request from '@/utils/request';

/** get接口 */
export async function postService(params: any) {
  return request('/aa/bb', {
    method: 'POST',
    data: params
  })
}
/** post接口 */
export async function getService (params: any) {
  return request('/aa/bb', {
    method: 'GET',
    params
  })
}
  1. interface.ts文件,一般用于存放ts类型
export interface ItemType {
  name: string
  age: numbernumber // | 标示或
  fn1: () => void // 无参数,无返回值
  fn2: (parame: number) => number // 数字格式参数且返回值为数字格式
  fn3: (parame?: number) => void // ?参数可传可不传
  fn4: (par1?: number, par2: number) => void // fn4(undefined, 6) 如果不想传第一个参数,可传undefined
}
export interface RouteParams {
	taskId: number
}

React Hooks(钩子)

  1. useState
const [list, setList] = useState<ItemType[]>([]) // 创建
setList([...list]) // 修改
  1. useEffect和useLayoutEffect

** 同步异步:数据变化后重构dom,useLayoutEffect为同步,在dom重构回流渲染完成后执行,useEffect为异步,和dom重构回流同步执行,所以操作dom建议放在useLayoutEffect里,但当有useLayoutEffect时,其他的useEffect因为执行顺序的问题也会变成了同步。
** 执行顺序:当useLayoutEffect和useEffect同时存在时,先调用useLayoutEffect,只有useEffect时,代码从上而下依次执行。

useEffect(() => {
  console.log('进入页面执行')
  return () => {
	console.log('页面销毁时执行')
  }
}, [])
useEffect(() => {
  console.log('监听list,useState钩子修改了list触发')
}, [list])
useLayoutEffect(() => {
  console.log('进入页面,我会先执行,操作渲染后的dom,在这里操作')
}, [])
  1. useRef
import React, { useRef } from 'react'

const Aaa = () => {
	const inputValue = useRef<String>('') // 创建
	inputValue.current = '新值' // 修改
	
	const inputDom = useRef<any>() // 创建
	inputDom.current.focus() // 获取dom并使input聚焦
	
	return (
	   <input ref={inputDom} type="text" />
	)
}

export default Aaa
  1. useMemo

** 数据变化后重构dom,useMemo是dom渲染前执行,useLayoutEffect是dom渲染后执行

import React, { useMemo } from 'react'
import { componentA, componentB } from '../components'

const App = () => {
	const [ flag, setFlag ] = useState<any>(1)
	
	const Component = useMemo(() => {
		console.log('当flag更新后,dom渲染前,触发这里,判断最终渲染哪个组件')
   		if (flag === 'A')  ComponentA
	   	if (flag === 'B')  ComponentB
	   	return ComponentC
	 }, [flag])


	return (
	   <Component type={flag} />
	)
}

export default App
  1. createContext和useContext

** 爷孙组件传值,和vue里的抽取注入类似

import React, { createContext, useContext } from 'react'

 // 1、创建,正常需要在爷组件和孙组件挨个引入创建的Context,这里为了方便写博客,爷孙组件都写在一个文件里
const Context = createContext({ name: '', age: 0 });

// 2、传值
const Ye = () => { // 爷组件
    const [ name, setName ] = useState('zs'); // 需要传递的值
    const [ age, setAge ] = useState(18); // 需要传递的值
    return (
        <div>
            {/** 需要用到变量的子组件一定要写在provider中间并用value传递 */}
            <Context.Provider value={{ name, age }}>
                <Fu />
            </Context.Provider>
        </div>
    );
};

const Fu = () => { // 父组件
  return (
      <div style={{ border: '1px solid' }}>
          <Sun />
      </div>
  );
};

// 3、取值
const Sun = () => { // 孙组件
  const yeData: any = useContext(Context);
  return (
      <div style={{ border: '1px solid' }}>
          <p>
              {yeData.name}:{yeData.age}
          </p>
      </div>
  );
};

export default Ye
  1. useReducer

** 和useState特性几乎完全相似,可被useEffect监听,并且修改后无法立刻获得最新值,如果多个值相互有关联,可用此钩子,单个值用useState

const [state, dispatch] = useReducer(x => x + 1, 0)
dispatch()-------------- ⬇️
const doFetchDataReducer = (state, action) => {
  switch (action.type) {
    case 'setData':
      return { ...state, data: action.payload }
    case 'setIsLoading':
      return { ...state, isLoading: action.payload }
    case 'setIsError':
      return { ...state, isError: action.payload }
    default:
      throw new Error()
  }
}
const [state, dispatch] = useReducer(
  doFetchDataReducer,
  { isLoading: false, isError: false, data: 0 }
)
dispatch({ type: 'setData', payload: '2' }) // 修改值
useEffect(() => {
  console.log('变了', state); // 可被useEffect监听
}, [state])

React Router(路由)
8. useHistory

import { useHistory, useParams } from 'umi'
const { push, replace, location, goBack, goForward, action, listen } = useHistory()

跳转及获参,push添加replace替换,用法完全一样
  第一种 // url里显示
	1.定义
	path: '/aa/bb/:id/:typeId'
	2.携参跳转
	push(`/aa/bb?id=${record.id}${record.typeId}`)
	3.获取
	const { id, typeId } = useParams<any>()
  第二种 // 显示
	1.定义
	path: '/aa/bb'
	2.携参跳转
	push(`/aa/bb?id=${record.id}&typeId=${record.typeId}`)path({pathname: '/home', query: {id: 1, typeId: 2}})
	3.获取
	const { id, typeId } = location.query
  第三种 // 不显示
	1. 定义
	path: '/aa/bb'
	2.携参跳转
	path('/aa/bb', {id: 1, typeId: 2})
	3.获取
	const { id, typeId } = location.state
  
返回
goBack()
前进
goForward()
获取pathname
const { pathname } = location // /aa/bb
获取跳转类型
const routerType = action // PUSH || REPLACE || ....
监听
listen(callback) // 每次触发都会重复挂载,挂载后任何页面跳转,只要路由变化,都会触发callback函数
const callback = (parameter, routerType) => {
	parameter = {
		pathname: "/aiLogin",
		query: {id: "1"},
		search: "?id=1",
		...
	} // 此页面路由数据
	router = 'PUSH' || 'REPLACE' // 跳转类型
}
  1. history
import { history } from 'umi'
用法和useHistory一样,区别是history是对象,useHistory是函数,需要先在顶部先定义然后调用()

useHistory
const a = useHistory()
a.push('...')
----
history
history.push('...')
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值