前言来到字节快一年了,最初的我满怀憧憬,以为大厂的代码一定是高深莫测、充满黑科技的艺术品。然而,深入项目后才发现,这里的代码并没有想象中那么“高大上”,反而透着一股朴实无华的实用主义!
今天主要说说这些朴实无华的实用主义!
正文朴实无华的内联原则首先,我先来说说第一次提交 MR 请求时,RV 的最多的问题:请用内联!
我以前的强迫症习惯(零散示例):
以前的习惯:常量必须放文件顶部!函数必须定义变量!
import React from 'react';import { Button, Form, Select } from "@arco-design/web-react";const sameOptions = [ { value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' },];const FormSelect = () => { const [form] = Form.useForm(); const submit = () => console.log(form.getFiledsValue()); return ( <Form form={form}> <Form.Item label="samelabel" field="same"> <select options={sameOptions} /> </Form.Item> <Form.Item > <Button onClick={submit}></Button> </Form.Item> </Form> );};export default FormSelect;
这种方式看似简洁,但在大项目中,文件多了,变量散了,容易造成“阅读障碍”。
现在,看内联方式
内联方式(朴实示例):
import React from 'react';import { Button, Form, Select } from "@arco-design/web-react";const FormSelect = () => { const [form] = Form.useForm(); return ( <Form> <Form.Item label="samelabel" field="same"> <select options={[ { value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' }, ]} /> </Form.Item> <Form.Item > <Button onClick={() => console.log(form.getFiledsValue())}></Button> </Form.Item> </Form> );};export default FormSelect;
这种代码更紧凑,一眼就能看懂逻辑。不用来回翻看跳转!日常维护也更容易一些!
当然,不是无脑内联,如果包含函数很复杂的计算,还是要求定义变量,因为每次 render 都进行复杂的计算,会导致页面卡顿!
看机会
技术大厂→机遇,前端-后端-测试,待遇和稳定性还不错,看机会试试~
朴实无华的变量还一个容易出现零散问题的地方:定义变量!
我以前的习惯
const App = () => { const [a, setA] = useState(0); const [b, setB] = useState(0); const [c, setC] = useState(0); const onAchange = (val) => setA(val); const onBchange = (val) => setB(val); const onCchange = (val) => setC(val); return <></>}
相信很多小伙伴都会这么写变量吧,但是这种在我们组是很难被通过的代码,因为同样会导致找不到变量在哪的情况!
我们组的方案,是使用了一个 useSetState 的 hook 定义,它返回常用的 state 还会返回一个 ref state !
先看看现在的写法吧!
现在的习惯
const App = () => { const { state, setRefState, getRefState } = useSetState({ a: 0, b: 0, c: 0 }) const onChange = (a, b, c) => setResState({ a, b, c }) return <></>}
这么写的好处,除了前面说到的变量在一块,方便查找外,还额外提供了 ref state ,如果页面仅仅是读取状态,那么可以使用它来减少无意义的页面渲染!
<div>{getRefState().a}</div>
朴实无华的中间量和函数定义另外一个 RV 的出现多次问题,就是因为我使用了 useCallback 还有 useMemo!
其实当如入职,组里的新手指引里,明确写了尽量不要使用他们,但是我写项目的时候还是用了,结果就是卡在这里无法通过 Merge !
const App = () => { const { state } = useSetState({}) // 不要使用 useMemo const d = state.a + state.b; // 不要使用 useCallback const onChange = (val) => { /**todo**/ } return <></>}
朴实无法的组件定义另外,给我很大震撼的是,我刚刚接手项目,一个文件居然放了好几个小组件和一个页面组件!
慢慢了解后才知道,原来是这样的:
- 1. 如果其他地方没有用到,不允许拆封组件(内联原则)
- 2. 一个页面的组件在多个地方使用才拆封组件,不考虑以后
- 3.一个页面的功能组件,尽量保留在一个文件里(不过度拆封文件)
具体的例子就不展示了,但是表达的意思就是:不要过度组件化、多文件化!
朴实无华的数据与 UI 的分离大厂项目强调可复用性,尤其是大型模块。数据逻辑(如 API 调用、状态管理)和 UI 渲染(如组件布局)如果耦合太紧,复用起来就麻烦。
关于状态分离,也有要求:没有跨页面跨模块的逻辑和 UI 没必要分离!
因为会破坏阅读代码的流畅性!
如果分离,我们组有专门的高阶组件工具!
下面是示例:
import { createStore } from "@/utils";import { useSetState } from "@/hooks";import { useState } from "react";export const useMaterialStore = () => { const { state, setRefState, getRefState } = useSetState({ a: 0, b: 0, c: 0 }) return { state, d: get () => state.a + state.b, setRefState, getRefState };};export const { useStore, withStoreProvider} = createStore(useMaterialStore);
import { withStoreProvider, useStore} from "./store";import Other fron "./Other.tsx"const Index = () => { const { state, d } = useStore(); return <Other />;};export default withStoreProvider(Index);
这样,Index 下的任意组件都可以使用 useStore 共享数据了!
UI 组件只需订阅 useStore,逻辑复用更灵活。
下面是我自己实现的 createStore:
import React, { createContext, useContext } from "react";import type { PropsWithChildren, ReactNode } from "react";export function createStore<TStore>(initializer: () => TStore) { const StoreContext = createContext<TStore>({} as TStore); // Provider 组件 function StoreProvider({ children }: { children: ReactNode }) { const store = initializer(); return <StoreContext.Provider value={store} >{children}</StoreContext.Provider> } // Hook:获取 store function useStore(): TStore { const store = useContext(StoreContext); if (!store) { throw new Error("useStore must be used within a StoreProvider"); } return store; } // 高阶组件:自动包裹 Provider function withStoreProvider( Component: (props: unknown) => ReactNode ): React.FC<PropsWithChildren> { return function (props: unknown) { return <StoreProvider>{Component(props)}</StoreProvider>; }; } return { useStore, withStoreProvider };}
最后在字节写代码,就是这么朴实无华且枯燥!而且还有很多实用的小技巧,有时间我再分享给大家!
今天的分享就这些了,感谢大家的阅读!如果文章中存在错误的地方欢迎指正!
——转载自:萌萌哒草头将军
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
×
|