Reactjs常用组件

2024-04-22 17:28
文章标签 组件 常用 reactjs

本文主要是介绍Reactjs常用组件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 react

1.1 useState

让函数组件具有维持状态的能力

const[count, setCount]=useState(0);

1.2 useEffect

执行副作用,useEffect 的第二个参数告诉 React 用到了哪些外部变量

类似于Vue watch的作用

useEffect(fn, deps);

1.每次 render 后执行:不提供第二个依赖项参数。

比如useEffect(() => {})。

2.仅第一次 render 后执行:提供一个空数组作为依赖项。

比如useEffect(() => {}, [])。

3.第一次以及依赖项发生变化后执行:提供依赖项数组。

比如useEffect(() => {}, [deps])。

4.组件 unmount 后执行:返回一个回调函数。

比如useEffect() => { return () => {} }, [])。
useEffect(() => {document.title = "Hello, " + name;
}, [name]);

1.3 useCallback

缓存回调函数。

useCallback(fn, deps)

useCallback是React Hooks中的一个函数,用于优化函数组件的性能。它的作用是返回一个memoized(记忆化的)函数,这个函数只有在依赖项发生变化时才会重新计算,否则会直接返回上一次计算的结果。 

例子:

import React, { useState, useCallback } from 'react';function Counter() {const [count, setCount] = useState(0);const handleIncrement = useCallback(() => setCount(count + 1),[count], // 只有当 count 发生变化时,才会重新创建回调函数);return <button onClick={handleIncrement}>+</button>
}

例子2:

import { useState, useCallback } from 'react';function MyComponent(props) {const [count, setCount] = useState(0);const handleClick = useCallback(() => {console.log(`Clicked ${count} times`);}, [count]);return (<><div>Count: {count}</div><button onClick={() => setCount(count + 1)}>Increment</button><button onClick={handleClick}>Click me</button></>);
}

1.4 useMemo

缓存计算的结果,类似于Vue中computed的作用

useMemo(fn, deps);

1.5 useRef

在多次渲染之间共享数据

const myRefContainer =useRef(initialValue);

1.6 useContext

定义全局状态

很多状态管理框架,比如 Redux,正是利用了 Context 的机制来提供一种更加可控的组件之间的状态管理机制。

1.7 createRef

创建一个 React ref 对象

import React, { createRef } from 'react';class MyComponent extends React.Component {constructor(props) {super(props);// 创建一个 ref 对象this.myRef = createRef();}render() {return (<div>{/* 将 ref 对象附加到一个 DOM 元素上 */}<input type="text" ref={this.myRef} /></div>);}
}

1.8 memo

React.memo 是 React 提供的一个高阶组件(Higher-Order Component),用于优化函数组件的性能。它类似于类组件中的 shouldComponentUpdate 方法,用于在 props 发生变化时判断是否重新渲染组件。

import React from 'react';const MyComponent = React.memo((props) => {// 在这里定义组件逻辑return (<div>{/* 使用 props 中的数据渲染组件 */}<h1>{props.title}</h1><p>{props.content}</p></div>);
});

1.9 组件创建

const ImgUpload: FC<IProps> = (props: IProps): ReactElement => {return (<div></div>)
};
export default memo(ImgUpload);

1.10 Suspense

就是一种加载组件优化,提升用户体验。

children:真正的 UI 渲染内容。

fallback:真正的 UI 未渲染完成时代替其渲染的备用 UI,它可以是任何有效的 React 节点。

import { Suspense } from 'react';
<Suspense fallback={<Loading />}><SomeComponent />
</Suspense>

2 Redux Toolkit

2.1 createSlice

接受初始状态的函数、reducer 函数的对象和“切片名称”, 并自动生成与 reducer 和 state 相对应的动作创建者和动作类型。类似于 Vue 中 Vuex 中的 store

function createSlice({//此状态切片的字符串名称。生成的操作类型常量将使用此作为前缀。name: string,// 此状态切片的初始状态值。initialState: State,//一个包含 Redux “case reducer” 函数的对象reducers: Record<string, ReducerFunction | ReducerAndPrepareObject>,// A "builder callback" function used to add more reducersextraReducers?: (builder: ActionReducerMapBuilder<State>) => void,// A preference for the slice reducer's location, used by `combineSlices` and `slice.selectors`. Defaults to `name`.reducerPath?: string,// An object of selectors, which receive the slice's state as their first parameter.selectors?: Record<string, (sliceState: State, ...args: any[]) => any>,
})

例子:

import { createSlice } from '@reduxjs/toolkit'const counterSlice = createSlice({name: 'counter',initialState: 0,reducers: {increment: (state) => state + 1,},
})

2.2 createAsyncThunk

一个接受 Redux 操作类型字符串的函数和一个应该返回 promise 的回调函数。通常用于处理异步逻辑。

// 创建一个异步的 Thunk action creator
export const getUserById = createAsyncThunk('user/getUserById', // 定义 action 的 typeasync (userId) => {// 异步逻辑,例如从服务器获取数据const response = await fetchUserById(userId);// 返回获取到的数据作为 action payloadreturn response.data;}
);

2.3 createAction

在 Redux 中定义动作的常用方法是分别声明一个动作类型常量和一个动作创建器函数来构造该类型的动作。与createAsyncThunk区别是:一个同步一个异步。

const INCREMENT = 'counter/increment'function increment(amount: number) {return {type: INCREMENT,payload: amount,}
}const action = increment(3)
// { type: 'counter/increment', payload: 3 }

2.4 createReducer

用于创建 Redux 中的 reducer

  • initialState :第一次调用 reducer 时应使用的初始状态。这也可能是一个“延迟初始值设定项”函数,该函数在调用时应返回初始状态值。每当调用 reducer with 作为其状态值时,都会使用它,并且主要用于从 中读取初始状态等情况。State | (() => State)undefinedlocalStorage
  • builder回调 接收要定义的构建器对象的回调 大小写缩减器通过调用 .(builder: Builder) => voidbuilder.addCase(actionCreatorOrType, reducer)
import { createReducer } from '@reduxjs/toolkit';// 定义初始状态
const initialState = {value: 0
};// 使用 createReducer 创建 reducer
const counterReducer = createReducer(initialState, {increment: (state) => {state.value += 1;},decrement: (state) => {state.value -= 1;},
});export default counterReducer;

3 react-redux

3.1 创建项目

npx create-react-app zhiqu-web-test --template typescript

3.2 useselector

共享状态,从Redux的store中提取数据(state)

const result: any = useSelector(selector: Function, equalityFn?: Function)

selector 在概念上大约等同于 mapStateToProps argument to connect。

selector 将以整个 Redux store state 作为唯一的参数被调用。每当函数组件渲染时,selector 就会被运行(除非在组件的前一次渲染后引用没有改变,这样 hooks 就会返回缓存的结果,而不是重新运行 selector)。useSelector() 也会订阅 Redux store,每当有 action 被 dispatched 时就会运行 selector。

全等比较和更新

默认的对比方式是严格的 === 引用比较

import { shallowEqual, useSelector } from 'react-redux'
const selectedData = useSelector(selectorReturningObject, shallowEqual)

 结合useEffect做全局的store监听:

const channel = useSelector<any, IChannel>((state) => {return state.channelReducer?.channel as IChannel;});
useEffect(() => {...}, [channel]);

3.3 configureStore

提供了一个简单而灵活的方式来创建 Redux store,使得 Redux 应用的设置过程更加轻松和高效。它是 Redux Toolkit 提供的一个重要工具,可以帮助开发者更快地搭建和管理 Redux 应用。

import { configureStore } from '@reduxjs/toolkit';
// ...const store = configureStore({reducer: {posts: postsReducer,comments: commentsReducer,users: usersReducer,},
});// 从 store 本身推断出 `RootState` 和 `AppDispatch` types
export type RootState = ReturnType<typeof store.getState>;
// 类型推断: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;

综合案例:使用 createSlice、createAsyncThunk 和 configureStore 

import { configureStore, createSlice, createAsyncThunk } from '@reduxjs/toolkit';// 定义一个异步 Thunk action creator
const fetchUserById = createAsyncThunk('users/fetchById',async (userId, thunkAPI) => {const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);return response.json();}
);// 定义一个初始状态
const initialState = {user: {},loading: false,error: null,
};// 创建一个 slice
const userSlice = createSlice({name: 'user',initialState,reducers: {changeUser(state, { payload }) {state.user= payload;},},extraReducers: (builder) => {builder.addCase(fetchUserById.pending, (state, action) => {state.loading = true;}).addCase(fetchUserById.fulfilled, (state, action) => {state.loading = false;state.user = action.payload;}).addCase(fetchUserById.rejected, (state, action) => {state.loading = false;state.error = action.error.message;});},
});// 导出 slice 中的 action creators
export const { changeUser } = userSlice.actions;// 创建 Redux store
const store = configureStore({reducer: userSlice.reducer,
});export default store;//将其分发到 Redux store 中。这样一来,Redux store 中的相应 reducer 将会根据'changeUser' //action 的类型来更新用户信息的状态。
store.dispatch(changeUser(user));import { type Dispatch } from 'redux';
dispatch(fetchUserById(userId));

在 Redux 应用中,store.dispatchdispatch 都用于触发 action,但它们的使用方式略有不同。

  1. store.dispatch: 用于分发 action 到 Redux store 中。它通常在组件外部被调用,比如在 Redux 相关的业务逻辑代码中或者 Redux 中间件中。示例:store.dispatch(action)

  2. dispatch: dispatch 是一个函数,通常通过 React Redux 提供的 useDispatch hook 或者 connect 函数的返回值来获取。它用于在 React 组件中分发 action。dispatch 函数本质上是 store.dispatch 的封装,用于在组件中直接触发 action,而不需要显式地引用 Redux store。示例:dispatch(action)

总的来说,store.dispatch 是 Redux store 实例的方法,用于在 Redux 应用的任意位置触发 action,而 dispatch 是一个函数,通常在 React 组件中使用,用于触发 action 并更新 Redux store 中的状态。

3.4 useDispatch 

const dispatch = useDispatch()

这个 hook 返回一个对 Redux store 中的 dispatch 函数的引用。dispatch结合store使用

import React from 'react'
import { useDispatch } from 'react-redux'export const CounterComponent = ({ value }) => {const dispatch = useDispatch()return (<div><span>{value}</span><button onClick={() => dispatch({ type: 'increment-counter' })}>Increment counter</button></div>)
}

3.5 useStore

为什么很少使用 useStore

  • 在 React Redux 中,useStore 允许你从默认的上下文中获取当前的 Redux store 实例。然而,它在实际开发中很少被使用,因为大多数情况下,我们不需要直接访问整个 store。
  • 使用 useStore 的主要原因是为了访问 store 的状态或执行一些自定义逻辑。但是,这通常不是最佳实践,因为 React Redux 提供了更高级的 API 来处理 store 交互,例如 useSelector 和 useDispatch
import React from 'react';
import { useStore } from 'react-redux';const MyComponent = () => {const store = useStore();const handleClick = () => {// 分发一个 action 到 Redux store 中store.dispatch({ type: 'SOME_ACTION' });// 获取当前 Redux store 中的状态const state = store.getState();console.log(state);};return (<button onClick={handleClick}>Dispatch Action</button>);
};export default MyComponent;

3.6 useselector

共享状态,从Redux的store中提取数据(state)

const result: any = useSelector(selector: Function, equalityFn?: Function)

selector 在概念上大约等同于 mapStateToProps argument to connect。

selector 将以整个 Redux store state 作为唯一的参数被调用。每当函数组件渲染时,selector 就会被运行(除非在组件的前一次渲染后引用没有改变,这样 hooks 就会返回缓存的结果,而不是重新运行 selector)。useSelector() 也会订阅 Redux store,每当有 action 被 dispatched 时就会运行 selector。

  const channel = useSelector<{ channelReducer: { channel: IChannel } }, IChannel>((state) => {return state.channelReducer.channel as IChannel;});

4 redux-immutable

4.1 combineReducers

组合reducer

import { combineReducers } from 'redux-immutable';
const reducer = combineReducers({loginReducer,channelReducer,queueReducer
});

5 react-router-dom

5.1 useNavigate

 用于在React应用程序中进行路由导航

const navigate = useNavigate();
navigate('/register', {replace: false});

5.2 useLocation

用于获取当前页面的 URL 信息。它返回一个包含当前 URL 信息的 location 对象,包括 pathname、search、hash 等属性。

import React from 'react';
import { useLocation } from 'react-router-dom';const MyComponent = () => {// 使用 useLocation hook 获取当前页面的 URL 信息const location = useLocation();return (<div><h1>当前页面的 URL 信息:</h1><p>Pathname: {location.pathname}</p><p>Search: {location.search}</p><p>Hash: {location.hash}</p></div>);
};export default MyComponent;

5.3 路由设置

路由配置:

import { Navigate, type RouteObject } from 'react-router-dom';
import { lazy, Suspense } from 'react';
const routes: RouteObject[] = [{path: '/',element: <Navigate to={LOGIN_PATH} />}
]
export { routes };

 项目启动入口:

import ReactDOM from 'react-dom/client';
import App from './App';
import './assets/css/base.css';
import './constant/format';
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(<App />);

 App.tsx配置:

import { Suspense, useEffect, type ReactElement } from 'react';
import { Provider } from 'react-redux';
import 'antd/dist/reset.css';
import { HashRouter, useRoutes, useLocation, useNavigate } from 'react-router-dom';
import { routes } from './router';
import store from './store';
import './store/actionCreators';
import ErrorBoundary from './components/error';
import { CommonWrapper } from './assets/css/common';function App(): ReactElement {function RouteElement(props: any) {return useRoutes(routes);}return (<CommonWrapper><div className="App"><Provider store={store}><HashRouter><Suspense fallback={<div>wwww</div>}><ErrorBoundary><RouteElement /></ErrorBoundary></Suspense></HashRouter></Provider></div></CommonWrapper>);
}export default App;

 通过useRoutes(routes)将路由加载进去

5.4 withRouter

withRouter 是 React Router 提供的一个高阶组件(Higher-Order Component),用于将路由信息注入到组件中。它可以将 React Router 的 history、location 和 match 对象作为 props 传递给被包裹的组件。

import React from 'react';
import { withRouter } from 'react-router-dom';const MyComponent = ({ history, location, match }) => {// 在组件中可以访问到 history、location 和 match 对象return (<div><h1>当前页面的路径:</h1><p>Pathname: {location.pathname}</p>{/* 其他路由信息 */}</div>);
};// 使用 withRouter 高阶组件包裹组件
export default withRouter(MyComponent);

5.5 错误页面定义 

import React from 'react';
import { useNavigate } from 'react-router-dom';
function withRouter(WrapperComponent: any) {return function (props: any) {const navigate = useNavigate();const router = { navigate };return <WrapperComponent {...props} router={router} />;};
}
export default withRouter;

通过withRouter定义错误页面:

import React, { type ReactElement } from 'react';
import { Button, Result } from 'antd';
import withRouter from '../../hook/withRouter/withRouter';interface IProps {children: ReactElement;router: any;
}
interface IState {hasError: boolean;
}
class ErrorBoundary extends React.PureComponent<IProps, IState> {constructor(props: any) {super(props);this.state = { hasError: false };}
//静态方法,用于捕获子组件渲染过程中发生的错误,并更新组件的状态。在这里,如果发生了错误,则将 hasError 状态设置为 true。static getDerivedStateFromError(error: any) {return { hasError: true };}
//生命周期方法,用于捕获子组件渲染过程中发生的错误,并打印错误信息。在这里,将错误信息打印到控制台。componentDidCatch(error: any, errorInfo: any) {console.log(error, errorInfo);}loginRouter(): void {const { navigate } = this.props.router;navigate('/home/recommend');window.location.reload();}render() {if (this.state.hasError) {return (<Resultstatus="404"title="错误"subTitle="抱歉,页面好像出现了一个未知错误,请点击下方按钮跳转至首页"extra={<Buttontype="primary"onClick={() => {this.loginRouter();}}>首页</Button>}/>);}return this.props.children;}
}export default withRouter(ErrorBoundary);

这篇关于Reactjs常用组件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/926399

相关文章

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

Linux上设置Ollama服务配置(常用环境变量)

《Linux上设置Ollama服务配置(常用环境变量)》本文主要介绍了Linux上设置Ollama服务配置(常用环境变量),Ollama提供了多种环境变量供配置,如调试模式、模型目录等,下面就来介绍一... 目录在 linux 上设置环境变量配置 OllamPOgxSRJfa手动安装安装特定版本查看日志在

Java常用注解扩展对比举例详解

《Java常用注解扩展对比举例详解》:本文主要介绍Java常用注解扩展对比的相关资料,提供了丰富的代码示例,并总结了最佳实践建议,帮助开发者更好地理解和应用这些注解,需要的朋友可以参考下... 目录一、@Controller 与 @RestController 对比二、使用 @Data 与 不使用 @Dat

Mysql中深分页的五种常用方法整理

《Mysql中深分页的五种常用方法整理》在数据量非常大的情况下,深分页查询则变得很常见,这篇文章为大家整理了5个常用的方法,文中的示例代码讲解详细,大家可以根据自己的需求进行选择... 目录方案一:延迟关联 (Deferred Join)方案二:有序唯一键分页 (Cursor-based Paginatio

Python实现常用文本内容提取

《Python实现常用文本内容提取》在日常工作和学习中,我们经常需要从PDF、Word文档中提取文本,本文将介绍如何使用Python编写一个文本内容提取工具,有需要的小伙伴可以参考下... 目录一、引言二、文本内容提取的原理三、文本内容提取的设计四、文本内容提取的实现五、完整代码示例一、引言在日常工作和学

Redis中的常用的五种数据类型详解

《Redis中的常用的五种数据类型详解》:本文主要介绍Redis中的常用的五种数据类型详解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Redis常用的五种数据类型一、字符串(String)简介常用命令应用场景二、哈希(Hash)简介常用命令应用场景三、列表(L

python中time模块的常用方法及应用详解

《python中time模块的常用方法及应用详解》在Python开发中,时间处理是绕不开的刚需场景,从性能计时到定时任务,从日志记录到数据同步,时间模块始终是开发者最得力的工具之一,本文将通过真实案例... 目录一、时间基石:time.time()典型场景:程序性能分析进阶技巧:结合上下文管理器实现自动计时

Spring组件初始化扩展点BeanPostProcessor的作用详解

《Spring组件初始化扩展点BeanPostProcessor的作用详解》本文通过实战案例和常见应用场景详细介绍了BeanPostProcessor的使用,并强调了其在Spring扩展中的重要性,感... 目录一、概述二、BeanPostProcessor的作用三、核心方法解析1、postProcessB

kotlin中的行为组件及高级用法

《kotlin中的行为组件及高级用法》Jetpack中的四大行为组件:WorkManager、DataBinding、Coroutines和Lifecycle,分别解决了后台任务调度、数据驱动UI、异... 目录WorkManager工作原理最佳实践Data Binding工作原理进阶技巧Coroutine

C#中的 Dictionary常用操作

《C#中的Dictionary常用操作》C#中的DictionaryTKey,TValue是用于存储键值对集合的泛型类,允许通过键快速检索值,并且具有唯一键、动态大小和无序集合的特性,常用操作包括添... 目录基本概念Dictionary的基本结构Dictionary的主要特性Dictionary的常用操作