React/TypeScript基础:如何将代码拆分至独立组件?
React组件拆分入门:物流计算器优化方案
针对你的物流计算器组件拆分需求,这里给你一套简单易懂的入门方案,核心围绕单一职责原则来拆分代码:每个组件只负责一件事,逻辑和UI尽量分离。
1. 封装购物车价值输入组件(CartValueInput)
把购物车价值的输入框、值的处理,以及和cartValue相关的附加费计算逻辑都塞进这个组件里,通过回调把值传递给父组件,让App组件不用关心这部分的细节。
import { useState } from 'react'; // 定义组件接收的参数类型 type CartValueProps = { onValueChange: (value: number) => void; // 可选:如果父组件需要用到计算后的附加费,可以加这个回调 onSurchargeChange?: (surcharge: number) => void; }; function CartValueInput({ onValueChange, onSurchargeChange }: CartValueProps) { const [localValue, setLocalValue] = useState(0); const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const inputValue = parseFloat(e.target.value) || 0; setLocalValue(inputValue); // 把输入值传递给父组件 onValueChange(inputValue); // 原本在App里的surcharge计算逻辑移到这里 const surcharge = inputValue < 100 ? 10 - inputValue : 30; onSurchargeChange?.(surcharge); }; return ( <div> <label>购物车价值</label> <input type="number" value={localValue} onChange={handleInputChange} />€ <br /> </div> ); } export default CartValueInput;
2. 封装计算按钮组件(CalculateFeeButton)
把提交按钮单独封装成组件,这样按钮的样式、文本都可以灵活配置,同时把提交逻辑通过回调交给父组件处理,保持组件的通用性。
type CalculateButtonProps = { onSubmit: (e: React.FormEvent<HTMLFormElement>) => void; buttonText?: string; }; function CalculateFeeButton({ onSubmit, buttonText = "计算配送费用" }: CalculateButtonProps) { return ( <button type="submit" onClick={(e) => onSubmit(e)}> {buttonText} </button> ); } export default CalculateFeeButton;
3. 提取配送费用计算逻辑为独立纯函数
把原本写在handleSubmit里的核心计算逻辑抽成单独的纯函数,这样不仅复用性高,还方便单独测试,也让App组件的代码更清爽。
// 定义计算参数的类型 type FeeCalcParams = { cartValue: number; deliveryDistance: number; }; export function calculateDeliveryFee({ cartValue, deliveryDistance }: FeeCalcParams): number { const baseFee = 5; let additionalFee = 5; if (deliveryDistance > 1000) { additionalFee = Math.ceil((deliveryDistance - 1000) / 500); additionalFee = additionalFee > 0 ? additionalFee : 1; } // 如果需要把surcharge加到总费用里,可以在这里加上 // const surcharge = cartValue < 100 ? 10 - cartValue : 30; // return baseFee + additionalFee + surcharge; return baseFee + additionalFee; }
4. 重构后的App组件
把拆分好的组件和函数整合起来,App组件只需要负责管理全局状态和协调各个子组件:
import { useState } from 'react'; import CartValueInput from './CartValueInput'; import CalculateFeeButton from './CalculateFeeButton'; import { calculateDeliveryFee } from './calculateDeliveryFee'; function App() { const [cartValue, setCartValue] = useState(0); const [deliveryDistance, setDeliveryDistance] = useState(0); const [fee, setFee] = useState(0); const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); // 调用独立的计算函数得到结果 const totalFee = calculateDeliveryFee({ cartValue, deliveryDistance }); setFee(totalFee); }; return ( <div> <h1>计算配送费用</h1> <form onSubmit={handleFormSubmit}> <CartValueInput onValueChange={setCartValue} /> <label>配送距离</label> <input type="number" value={deliveryDistance} onChange={(e) => setDeliveryDistance(parseFloat(e.target.value) || 0)} />英里 <CalculateFeeButton onSubmit={handleFormSubmit} /> </form> <h3>配送费用:{fee} USD</h3> </div> ); } export default App;
拆分思路总结
- UI与逻辑分离:输入、按钮这类UI组件只负责渲染和传递交互,核心计算逻辑放在纯函数里。
- Props传递:子组件通过props接收父组件的状态更新回调,把用户输入或计算结果回传给父组件。
- 单一职责:每个组件只聚焦一件事,比如CartValueInput只处理购物车价值的输入和相关计算,避免App组件臃肿。
内容的提问来源于stack exchange,提问作者KJM
相关产品推荐
相关产品推荐

