您的位置:首页 > 房产 > 家装 > 一个app多少钱_软件定制公司值得去吗_百度网盘官网登陆入口_seo网站关键词排名优化

一个app多少钱_软件定制公司值得去吗_百度网盘官网登陆入口_seo网站关键词排名优化

2024/12/23 8:40:22 来源:https://blog.csdn.net/XiugongHao/article/details/144130197  浏览:    关键词:一个app多少钱_软件定制公司值得去吗_百度网盘官网登陆入口_seo网站关键词排名优化
一个app多少钱_软件定制公司值得去吗_百度网盘官网登陆入口_seo网站关键词排名优化

以下为知行小课学习笔记。

概述

在这里插入图片描述

Context 跨组件共享状态

在 Next 项目,封装 useContext。

AppContext.tsx

"use client";import React, {createContext, Dispatch, ReactNode, SetStateAction, useContext, useMemo, useState} from 'react';type State = {displayNavigation: boolean;themeMode: 'light' | 'dark';
};type AppContextProps = {state: StatesetState: Dispatch<SetStateAction<State>>
}const AppContext = createContext<AppContextProps>(null!)export function useAppContext() {return useContext(AppContext)
}export default function AppContextProvider({children}: { children: ReactNode }) {const [state, setState] = useState<State>({displayNavigation: true, themeMode: 'light'})// 性能优化const contextValue = useMemo(() => {return {state, setState}}, [state, setState])return <AppContext.Provider value={contextValue}>{children}</AppContext.Provider>
}

使用自定义封装的 useContext 和 ContextProvider 。

layouts.tsx

import type {Metadata} from "next";
import "./globals.css";
import AppContextProvider from "@/components/AppContext";export const metadata: Metadata = {title: "XIU-GPT",
};export default function RootLayout({children,
}: Readonly<{children: React.ReactNode;
}>) {return (<html lang="zh"><body><AppContextProvider>{children}</AppContextProvider></body></html>);
}

Toolbar.tsx

"use client"
import React from 'react';
import Button from "@/components/common/Button";
import {useAppContext} from "@/components/AppContext";
import {MdDarkMode, MdInfo, MdLightMode} from "react-icons/md";function Toolbar() {const {state: {themeMode}, setState} = useAppContext()return (<div className={`absolute left-0 right-0 bottom-0 dark:bg-gray-800 dark:border-gray-800 border-t-2 flex p-2 justify-between`}><Button icon={themeMode === 'dark' ? MdDarkMode : MdLightMode} variant="text"onClick={() => {setState((prevState) => {return {...prevState,themeMode: prevState.themeMode === 'dark' ? 'light' : 'dark'}})}}/><Button icon={MdInfo} variant="text"/></div>);
}export default Toolbar;

Reducer 复杂状态管理

setState 如果每次执行只是更新少量 state ,但都需要重新 set 所有 state,更新状态会变得繁琐,尤其是在 state 层级较多的情况下。useReducer 抽离 setState 逻辑,更好管理状态。

reducers/AppReducers.ts

import {ReducerWithoutAction} from "react";export type State = {displayNavigation: boolean;themeMode: 'light' | 'dark';
};export enum ActionType {UPDATE = "UPDATE"
}type UpdateAction = {type: ActionType.UPDATE;field: string;value: any;
}export type Action = UpdateAction;export const initState: State = {displayNavigation: true,themeMode: 'light'
}export function reducer(state: State, action: Action) {switch (action.type) {case ActionType.UPDATE:return { ...state, [action.field]: action.value}default: throw new Error(`Unhandled action type: ${action.type}`)}
}

AppContext.tsx

"use client";import React, {createContext, Dispatch, ReactNode, ReducerWithoutAction, useContext, useMemo, useReducer} from 'react';
import {Action, initState, reducer, State} from "@/reducers/AppReducers";type AppContextProps = {state: Statedispatch: Dispatch<Action>
}const AppContext = createContext<AppContextProps>(null!)export function useAppContext() {return useContext(AppContext)
}export default function AppContextProvider({children}: { children: ReactNode }) {const [state, dispatch] = useReducer(reducer as ReducerWithoutAction<any>, initState, () => {return initState})const contextValue = useMemo(() => {return {state, dispatch}}, [state, dispatch])return <AppContext.Provider value={contextValue}>{children}</AppContext.Provider>
}

Toolbar.tsx

"use client"
import React from 'react';
import Button from "@/components/common/Button";
import {useAppContext} from "@/components/AppContext";
import {MdDarkMode, MdInfo, MdLightMode} from "react-icons/md";
import {ActionType} from "@/reducers/AppReducers";function Toolbar() {const {state: {themeMode}, dispatch} = useAppContext()return (<div className={`absolute left-0 right-0 bottom-0 dark:bg-gray-800 dark:border-gray-800 border-t-2 flex p-2 justify-between`}><Button icon={themeMode === 'dark' ? MdDarkMode : MdLightMode} variant="text"onClick={() => {dispatch({type: ActionType.UPDATE,field: "themeMode",value: themeMode === 'dark' ? 'light' : 'dark'})}}/><Button icon={MdInfo} variant="text"/></div>);
}export default Toolbar;

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com