為什麼需要 Currying(柯里化)
簡單說有幾個好處:
One at a Time(一次處理一個參數),每個 function 可以各自處理傳入的參數,藉此提高程式的彈性
也因為拆分成許多片段,所以可以更好地重複利用
例子:
假設今天要計算一個商品的售價,那剛好今天全館商品打 8 折,
在沒有 Currying 的情況下的計算函式會像下面這樣
function calcDiscountPrice(price, discount) {
return price * discount;
}
calcDiscountPrice(100, 0.8); //80
calcDiscountPrice(80, 0.8); //64
轉成 Curry function 之後:
function calcDiscountPrice(discount) {
return function (price) {
return price * discount;
};
}
const calcWith20PercentOff = calcDiscountPrice(0.8);
calcWith20PercentOff(100); //80
calcWith20PercentOff(80); //64
看出差別了嗎?當我們遇到全館商品都打 8 折的情況下,就不需要每次計算價格時,都還要再帶入一次折扣,一方面減少錯誤機率,另一方面也可以提高程式擴充性
在 React 上的實際應用
在沒有使用 Curry function 的情況下,每個 onChange 事件我們都要寫一個 function 來儲存他的值,那如果我們有一大堆的 input 需要儲存呢?那我們就需要寫很攏長的程式碼來處理它
export default function App() {
const [user, setUser] = useState({
name: '',
age: '',
phone: ''
});
// First handler
const handleNameChange = (e) => {
setUser((prev) => ({
...prev,
name: e.target.value
}));
};
// Second handler
const handleAgeChange = (e) => {
setUser((prev) => ({
...prev,
age: e.target.value
}));
};
// Third handler
const handlePhoneChange = (e) => {
setUser((prev) => ({
...prev,
phone: e.target.value
}));
};
return (
<>
<input value={user.name} onChange={handleNameChange} />
<input value={user.age} onChange={handleAgeChange} />
<input value={user.phone} onChange={handlePhoneChange} />
</>
);
}
轉成 Curry function 之後,我們可以透過傳遞要修改的 field 作為第一個參數來控制要修改的值是哪個,只需要一個 curry function 就可以避免原本需要寫一堆 function 的情況了
export default function App() {
const [user, setUser] = useState({
name: '',
age: '',
phone: ''
});
const handleInputChange = (field) => {
return (e) => {
setUser((prev) => ({
...prev,
[field]: e.target.value
}));
};
};
return (
<>
<input value={user.name} onChange={handleInputChange('name')} />
<input value={user.age} onChange={handleInputChange('age')} />
<input value={user.phone} onChange={handleInputChange('phone')} />
</>
);
}
Top comments (0)