react 给了开发者很多自由,但自由也可能带来问题:代码不一致、难以维护、团队协作困难。使用经过验证的设计模式可以避免这些问题。
下面介绍9个实用的 React 组件架构模式。这些模式能帮助你构建更健壮的 UI 界面。
这个模式把组件分成两类:
容器组件:负责数据处理和逻辑
展示组件:只负责显示界面
这样做的好处是逻辑和界面清晰分离。展示组件没有副作用和状态,更容易复用和测试。
// 容器组件
function UserContainer() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchUser().then(data => {
setUser(data);
setLoading(false);
});
}, []);
return <UserProfile user={user} loading={loading} />;
}
// 展示组件
function UserProfile({ user, loading }) {
if (loading) return <div>加载中...</div>;
if (!user) return <div>用户不存在</div>;
return (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
);
}
受控组件由父组件通过 props 管理值,非受控组件自己管理状态。
// 受控组件
function ControlledInput() {
const [value, setValue] = useState('');
return <input value={value} onChange={e => setValue(e.target.value)} />;
}
// 非受控组件
function UncontrolledInput() {
const inputRef = useRef();
return <input defaultValue="初始值" ref={inputRef} />;
}
受控组件更适合表单集成,非受控组件渲染更快。
通过 Context 共享状态,让相关组件一起工作。
const TabsContext = createContext();
function Tabs({ children, defaultValue }) {
const [activeTab, setActiveTab] = useState(defaultValue);
return (
<TabsContext.Provider value={{ activeTab, setActiveTab }}>
<div className="tabs">{children}</div>
</TabsContext.Provider>
);
}
function TabList({ children }) {
return <div className="tab-list">{children}</div>;
}
function Tab({ value, children }) {
const { activeTab, setActiveTab } = useContext(TabsContext);
return (
<button
className={activeTab === value ? 'active' : ''}
onClick={() => setActiveTab(value)}
>
{children}
</button>
);
}
使用方式:
<Tabs defaultValue="first">
<TabList>
<Tab value="first">第一个</Tab>
<Tab value="second">第二个</Tab>
</TabList>
</Tabs>
通过函数 prop 共享组件逻辑。
function Toggle({ children }) {
const [on, setOn] = useState(false);
const toggle = () => setOn(!on);
return children({ on, toggle });
}
// 使用
<Toggle>
{({ on, toggle }) => (
<button onClick={toggle}>
{on ? '开启' : '关闭'}
</button>
)}
</Toggle>
提供逻辑和状态,但不控制界面展示。
function useDropdown() {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => setIsOpen(!isOpen);
return { isOpen, toggle };
}
// 使用
function MyDropdown() {
const { isOpen, toggle } = useDropdown();
return (
<div>
<button onClick={toggle}>
菜单 {isOpen ? '▲' : '▼'}
</button>
{isOpen && (
<div className="dropdown-menu">
<div>选项一</div>
<div>选项二</div>
</div>
)}
</div>
);
}
允许使用者自定义状态更新逻辑。
function useToggle({ reducer = (state, action) => {
switch (action.type) {
case 'toggle':
return { on: !state.on };
default:
return state;
}
} } = {}) {
const [state, dispatch] = useReducer(reducer, { on: false });
const toggle = () => dispatch({ type: 'toggle' });
return [state.on, toggle];
}
智能组件处理业务逻辑,纯展示组件只负责显示。
// 智能组件
function ProductListContainer() {
const [products, setProducts] = useState([]);
useEffect(() => {
fetchProducts().then(setProducts);
}, []);
return <ProductList products={products} />;
}
// 纯展示组件
function ProductList({ products }) {
return (
<div className="product-list">
{products.map(product => (
<div key={product.id} className="product-item">
<h3>{product.name}</h3>
<p>价格: {product.price}元</p>
</div>
))}
</div>
);
}
把状态和逻辑放在使用它们的地方,不要过早抽象。
// 好的做法:状态就近放置
function LoginForm() {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
// 处理登录逻辑
};
return (
<form onSubmit={handleSubmit}>
<input
value={username}
onChange={e => setUsername(e.target.value)}
placeholder="用户名"
/>
<input
type="password"
value={password}
onChange={e => setPassword(e.target.value)}
placeholder="密码"
/>
<button type="submit">登录</button>
</form>
);
}
只有在确实需要复用时,才提取自定义 Hook。
用 props 配置组件行为,用 children 组合界面。
function Card({ variant = 'default', children }) {
return (
<div className={`card card-${variant}`}>
{children}
</div>
);
}
function CardHeader({ children }) {
return <div className="card-header">{children}</div>;
}
function CardBody({ children }) {
return <div className="card-body">{children}</div>;
}
使用方式:
<Card variant="primary">
<CardHeader>
<h3>卡片标题</h3>
</CardHeader>
<CardBody>
<p>卡片内容...</p>
</CardBody>
</Card>
这些模式不是必须严格遵守的规则,而是经过验证的最佳实践。根据项目需求选择合适的模式:
需要逻辑与界面分离时,使用容器/展示组件模式
构建复杂交互组件时,考虑复合组件模式
需要高度自定义界面时,使用无头组件模式
保持代码简单,避免过早抽象
好的组件设计让代码更容易维护、测试和扩展。开始在实践中应用这些模式,你会发现 React 开发变得更加顺畅。
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!
架构和框架是独立的,本文仅仅是提出一种架构思路,而且这个架构也在百度的某款用户量很大的复杂前端产品中得以应用。基于这一套弹性架构并结合Vue/React的现代化开发理念,可以很好的完成高复杂度的前端系统。
软件架构(software architecture)是一系列相关的抽象模式,用于指导大型软件系统各个方面的设计。传统软件架构描述的对象是直接构成系统的抽象组件,侧重于系统的抽象、拆分、组织方式等
架构师的一个重要职责是,确保团队有共同的技术愿景,以帮助我们向客户交付他们想要的系统。在某些场景下,架构师只需要和一个团队一起工作,这时他们等同于技术引领者。在其他情况下,他们要对整个项目的技术愿景负责,通常需要协调多个团队之间,甚至是整个组织内的工作。
C/S 架构是一种典型的两层架构,其全程是Client/Server,即客户端服务器端架构,其客户端包含一个或多个在用户的电脑上运行的程序,而服务器端有两种,一种是数据库服务器端,客户端通过数据库连接访问服务器端的数据
目的为保证服务器硬件故障时依然可用,数据依然保持并能够访问,手段:数据和服务的冗余备份以及失效转移机制,有状态 :在服务端保留之前的请求信息,用以处理当前请求(例如:session)无状态 :没有特殊状态的服务
动态应用,是相对于网站静态内容而言,是指以c/c++、php、Java、perl、.net等服务器端语言开发的网络应用软件,比如论坛、网络相册、交友、BLOG等常见应用。动态应用系统通常与数据库系统、缓存系统、分布式存储系统等密不可分。
本来没想写这个题材的,为了某某童鞋能够更好的茁壮成长,临时写一篇负载均衡的。负载均衡,大家可能听过什么3层负载均衡、4层负载均衡、7层负载均衡什么的?那这是怎么分的呢,ok,是根据osi七层网络模型来分的,例如nginx是工作在应用层
Kubernetes(k8s)是一款开源的优秀的容器编排调度系统,其本身也是一款分布式应用程序。虽然本系列文章讨论的是互联网架构,但是k8s的一些设计理念非常值得深思和借鉴,本人并非运维专家,本文尝试从自己看到的一些k8s的架构理念结合自己的理解来分析 k8s在稳定性
一般来说,除了当前的系统功能需求外,软件架构还需要关注性能、可用性、伸缩性、扩展性和安全性这5个架构要素。性能是网站的一个重要指标,任何软件架构设计档案都必须考虑可能会带来的性能问题。
本章介绍如何去构建高可用的服务,关键词:服务分级,超时设置,异步调用,服务降级,幂等性设计,一些架构设计中的常用方案,但是需要结合实际业务场景进行设计,没有一套方案能解决所有问题
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!