Chakra UI源码解读:理解抽象的价值
在我们的开发过程中,抽象是我们经常使用的一个概念,通过它,我们可以将复杂的代码逻辑进行简化,同时提高代码的可维护性和可重用性。本文是对Reading Code - Chakra UI的读后笔记,我们将从实际代码中探讨抽象的价值。
React.forwardRef的抽象
在没有使用forwardRef的情况下,我们处理ref可能需要这样:
class MyComponent extends React.Component {
myRef = React.createRef();
render() {
return <div ref={this.myRef} />;
}
}
// 父组件中
class Parent extends React.Component {
render() {
// 无法直接将 ref 传递给 MyComponent
return <MyComponent />;
}
}
使用forwardRef后,可以直接将ref传递给子组件:
const MyComponent = React.forwardRef((props, ref) => {
return <div ref={ref} />;
});
// 父组件中
class Parent extends React.Component {
myRef = React.createRef();
render() {
// 可以直接将 ref 传递给 MyComponent
return <MyComponent ref={this.myRef} />;
}
}
自定义Hooks的抽象
例如获取用户的位置信息,没有使用自定义Hooks前,我们可能需要在每个组件中重复写这段逻辑:
function MyComponent() {
const [position, setPosition] = useState(null);
useEffect(() => {
navigator.geolocation.getCurrentPosition((pos) => {
setPosition(pos);
});
}, []);
// ...
}
通过自定义Hook,我们可以将这段逻辑抽象出来:
function useUserPosition() {
const [position, setPosition] = useState(null);
useEffect(() => {
navigator.geolocation.getCurrentPosition((pos) => {
setPosition(pos);
});
}, []);
return position;
}
// 在组件中使用
function MyComponent() {
const position = useUserPosition();
// ...
}
对React Context的抽象
未使用createContext抽象前,我们通常这样创建和使用Context:
const MyContext = React.createContext();
function MyComponent() {
const myValue = useContext(MyContext);
// ...
}
使用createContext抽象后,我们可以更方便地创建和使用Context:
const [MyProvider, useMyContext] = createContext();
function MyComponent() {
const myValue = useMyContext();
// ...
}
Proxy设计模式的抽象
未使用Proxy之前,我们可能需要创建多个函数来处理不同的元素:
function createDiv() { /* ... */ }
function createSpan() { /* ... */ }
function createP() { /* ... */ }
使用Proxy后,我们可以使用单个函数来处理所有元素:
const chakra = factory();
chakra.div();
chakra.span();
chakra.p();
在样式设计中,对Emotion(一个流行的CSS-in-JS
库)的抽象
原先的代码可能是这样的:
const MyComponent = () => {
const style = {
color: 'red',
fontSize: '16px',
};
return <div style={style}>Hello World</div>;
};
使用styled函数,你可以将样式与组件分离:
const MyComponent = styled.div`
color: red;
font-size: 16px;
`;
// 在组件中使用
const SomeComponent = () => <MyComponent>Hello World</MyComponent>;
以上例子中,你可以看到,通过引入抽象,我们大大地提高了代码的可读性和可维护性。希望这篇文章能帮你在编程实践中更好地理解和使用抽象。