在组件开发中引用方式写法如下:
import Popup from '../Popup'import List from '../List'console.log(Popup, List) // f Popup f List
而不要使用如下写法:
import { Popup, List } from '../index' // 这样子引用会带进当前开发的组件本省console.log(Popup, List) // undefined undefined
原因是因为下面这种写法会带进当前开发的组件本身从而导致循环引用。循环引用会导致在编译态输出的结果为 undefined。
尽管受控模式相对非受控模式会多传入 value
、onChange
属性, 但它能有效避免组件库中碰到的一些反模式的坑。
在 Dan 的 编写具有弹性的组件一文中写到如下几个原则:
props
赋给 state
理由: 如果不结合 componentDidUpdate
使用会无法读取到更新的数据; 结合了 componentDidUpdate
在其进行 setState
又会进行多一次的 render。
解决方案
针对一些复杂数据使用 useMemo 以及 memorize-one 进行处理。或者
hooks
中在 render 内使用useMemo
;class
中在 render 内使用memorize-one
针对 TypeScript
中的 interface
中必填可填(是否带 ? 可选)与 React 中的 defaultProps
是不兼容的。造成的影响是 defaultProps
里若是不填写完整 TypeScript
中的 interface
属性则会标红。为了解决这个现象解决方案如下:
interface {mustFillIn: number,mayFillWithDefaultValue: number, // 可选的带默认值的不用带上问号mayFillWithoutDefaultValue?: number // 可选的不带默认值的带上问号}
在 TypeScript
中书写 React
时可以这样:
class Divider extends React.Component<DividerProps, any> {static defaultProps: Pick<DividerProps, 'mayFillWithDefaultValue' | 'mayFillWithoutDefaultValue'> = {mayFillWithDefaultValue: 12345}render() {return (<div>demo</div>)}}
const demo = () => {return new Promise((resolve) => {setTimeout(() => {console.log('模拟异步接口')resolve()}, 2000)})}
done()
来告知组件已完成异步操作;(组件内完成对 Promise 的封装)const demo = (done) => {setTimeout(() => {console.log('模拟异步接口')done()}, 2000)}
从组件设计的角度来说, 方式一对组件内部的维护更加友好; 从使用者的角度来说, 方式二的使用更为便捷, 但是重构的成本会变大。
如下是针对方式二的组件的封装方式。
// 此处 fn 为外面传入的 demo 函数if (fn.length === 1) {new Promise((resolve: any) => {fn(resolve)}).then(() => {...})}
背景: 业务 a 使用了组件包 b 以及工具包 c, 其中 c 也依赖了旧版本的 b。此时业务 a 中会有两个组件包 b 的样式, 此时会碰到修改了组件包 b 的样式, 而样式被老版本的 b 覆盖的情况。这个时候有什么解决方法呢?
pureDependencies
中, 业务方的 dependency
统一维护组件包 b;方法: src 目录下的组件中的 style 文件中建立 index.tsx 文件
scss
post-install
e2e 测试
random notes
sass 技巧
interpolation
, 让同质化分支模版化
• 逻辑关系组织 : 如 “颜色管理方案”如何统计组件使用量
DRY 原则: Don't Repeat Youself
Some of these CSS properties have shorthand versions that use the namespace as the property name. For these, you can write both the shorthand value and the more explicit nested versions.
.info-page {margin: auto {bottom: 10px;top: 2px;}}
比如添加了 A 属性 B 属性在某些情况会失效。又或者 C 属性必须在 D 属性存在的时候才生效。
比如以 Upload 组件为例: 背景逻辑是: 最大上传图片数量是 2, 当上传了 2 张图片以后就不显示继续上传了。
showAdd = () => {const { selectable, maxLength, files } = this.propsif (maxLength !== undefined) {if (files.length >= maxLength) {return false}return true}return selectable}
业务方举了反例: 例如有些商品图片是标品,图片是平台自己控制的,也许不满足最大数,但是不允许商家去修改的。 配置了 maxLength={10}, 图片数量只有 3 张时, 不显示增加按钮的需求当前就不能实现。