使用场景

有一些页面,可以让用户自由配置页面的显示方案。

例如用户详情页,可能包含了很多个 div,每个 div 是用户相关的属性,那么就可以提供给用户自由配置 div 顺序的能力。

设计

在这个方案中,有两个关键属性,三个关键能力,以及一些优化点。

  1. 两个关键属性:pageConfigId 和 pageConfig。
    1. 需要重点说明的是,这里一定要使用 id 进行封装,建立从 id 到 config 的对应关系,以方便后续的处理。
  2. 三个关键能力:读取页面配置,更改页面配置,根据页面配置渲染页面。
    1. 读取页面配置
      1. 可以通过一个函数来实现,传入 id,返回 config。需要注意的是,这个函数往往是异步函数,所以还需要一个属性:pageConfigLoading。
    2. 更改页面配置
      1. 可以通过更改 pageConfigId 来实现,pageConfigId 的修改造成了 pageConfig 的修改。
    3. 根据页面配置渲染页面
      1. 这里就自由发挥的,主要是要规定好配置的类型。
  3. 一些优化点
    1. 读取页面配置时的 loading 状态、失败状态处理。
    2. 配置的本地存储。
    3. 当前配置,本地存储配置的展示。

      实现

      ```typescript

import { useAsyncEffect } from ‘ahooks’ import { Dispatch, useCallback, useState } from ‘react’

export type UsePageConfigParams = { /** 根据 id 获取配置

    • 无论是否是异步函数,处理时都会当作异步函数来处理 / getPageConfig: (id: string) => TConfig | Promise defaultPageConfigId?: string /** 如果给定,则会将 page config id 存储到本地中 / localStorageKey?: string }

export type UsePageConfigReturns = { pageConfigId: string setPageConfigId: Dispatch pageConfigLoading: boolean pageConfig: TConfig / 从 localStorage 中获取存储的 id,如果没有配置 ,则返回 undefined */ getIdFromLocal: () => string / 将 id 存储进 localStorage */ setIdToLocal: () => void }

export function usePageConfig( params: UsePageConfigParams, ): UsePageConfigReturns { const { defaultPageConfigId, getPageConfig, localStorageKey } = params

const [pageConfigId, setPageConfigId] = useState( defaultPageConfigId ?? localStorage.getItem(localStorageKey), ) const [pageConfigLoading, setPageConfigLoading] = useState(false) const [pageConfig, setPageConfig] = useState(undefined)

useAsyncEffect(async () => { setPageConfigLoading(true) const res = await getPageConfig(pageConfigId) setPageConfig(res) setPageConfigLoading(false) }, [pageConfigId])

const getIdFromLocal = useCallback(() => { if (localStorageKey) { return localStorage.getItem(localStorageKey) } return }, [])

const setIdToLocal = useCallback(() => { localStorageKey && localStorage.setItem(localStorageKey, pageConfigId) }, [pageConfigId])

return { pageConfigId, setPageConfigId, pageConfigLoading, pageConfig, getIdFromLocal, setIdToLocal, } }

```