React自定義tab組合組件的實例詳解
前言
以前工作中一直使用的vue開發(fā),最近開始寫react的項目,發(fā)現(xiàn)好多基礎(chǔ)都不會,導致在項目開發(fā)中踩坑。這個系列我打算,從學習中實踐,直到最后完全掌握react。
自定義Tab
我們平時用的React庫,Tab組件和子組件都是組合使用的,像element的React庫,Tabs.Item是套在Tabs組件里面的,在React的寫法里面,組件是作為children傳遞到父組件里面的。像這種組合的寫,父組件怎么拿到子組件的狀態(tài),從而產(chǎn)生聯(lián)動。

既然能夠拿到children,那么通過children就可以監(jiān)聽到子組件的狀態(tài)變化了。這里要用到一個React的核心api,cloneElement。這個api克隆的是組件,不是元素。
const newElement = React.cloneElement( element, // 要克隆的目標元素(必須是合法的 React 元素,比如 <TabItem />) [props], // 可選:要新增/覆蓋的 props(會和原元素 props 合并) [...children] // 可選:要替換的子元素(不傳則保留原元素的子元素) );
實現(xiàn)代碼
通過cloneElement這個方法我們可以對組件進行處理,從而監(jiān)聽子組件的狀態(tài),實現(xiàn)聯(lián)動。以下是完整代碼。
import React, { useState, useCallback } from 'react';
import './custom-test-tab.css';
export const TabItem = ({
children,
label = '',
value,
onHandleClick,
onClick = () => { },
active = false
}) => {
const renderClass = () => {
return `tab-item ${active ? 'active' : ''}`;
}
const handleClick = (e) => {
onHandleClick && onHandleClick(value, e);
onClick(e);
};
return (
<div className={renderClass()} onClick={handleClick}>
{ label || children }
</div>
);
};
export const Tab = function ({ children, active = '', onChange = () => { } }) {
const [activeTab, setActiveTab] = useState(active);
// 2. 修復handleClick參數(shù)邏輯 + 補充依賴數(shù)組
const handleClick = useCallback((value) => {
if (value === undefined) return; // 防止空值
setActiveTab(value);
onChange(value);
}, [onChange]); // 依賴數(shù)組補充onChange,避免閉包問題
const createdTabs = () => {
return React.Children.map(children, (child) => {
// 安全校驗:只處理TabItem類型的子組件
if (!React.isValidElement(child) || child.type !== TabItem) {
return child;
}
return React.cloneElement(child, {
onHandleClick: handleClick, // 直接傳遞函數(shù),無需包裝
active: activeTab === child.props.value,
});
});
};
return (
<div className={'custom-test-tab'}>
{createdTabs()}
</div>/
);
};
// 3. 確保Tab.Item正確掛載
Tab.Item = TabItem;
export default Tab;使用自定義的Tab
import { useState} from "react";
import { Tab, TabItem } from "../components/custom-test-tab";
export const TestTab = () => {
const [active, setActive] = useState('蘋果');
const onChange = (value) => {
setActive(value);
};
const tabList = [
{ label: "蘋果", value: "蘋果", bgColor: "#FF5252" }, // 蘋果 - 紅色
{ label: "香蕉", value: "香蕉", bgColor: "#FFC107" }, // 香蕉 - 黃色
{ label: "橘子", value: "橘子", bgColor: "#FF9800" }, // 橘子 - 橙色
{ label: "葡萄", value: "葡萄", bgColor: "#9C27B0" }, // 葡萄 - 紫色
{ label: "鳳梨", value: "鳳梨", bgColor: "#4CAF50" }, // 鳳梨 - 綠色
];
const ContentView = ({ active }) => {
const item = tabList.find(item => item.value === active);
if (!item) return null;
return (
<div style={
{
backgroundColor: item.bgColor,
width: "100%",
height: '200px'
}
}>
{active === "蘋果" && <div>蘋果</div>}
{active === "香蕉" && <div>香蕉</div>}
{active === "橘子" && <div>橘子</div>}
{active === "葡萄" && <div>葡萄</div>}
{active === "鳳梨" && <div>鳳梨</div>}
</div>
);
};
return (
<div>
<h1>自定義組件</h1>
<Tab onChange={onChange} active={active}>
{
tabList.map((item, index) => (
<TabItem key={index} label={item.label} value={item.value}>
{item.label}
</TabItem>
))
}
</Tab>
<Tab onChange={onChange} active={active}>
{
tabList.map((item, index) => (
<Tab.Item key={index} label={item.label} value={item.value}>
{item.label}
</Tab.Item>
))
}
</Tab>
<ContentView active={active} />
</div>
);
};
export default TestTab;渲染效果

總結(jié)
證明封裝的Tab組件是可以的,通過這個Tab組件的封裝,不止是學會了封裝這個組件,還通過這個過程學會了,組合組件封裝的過程。
到此這篇關(guān)于React學習之自定義tab組合組件的文章就介紹到這了,更多相關(guān)React自定義tab組合組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React實現(xiàn)控制減少useContext導致非必要的渲染詳解
這篇文章主要介紹了React如何有效減少使用useContext導致的不必要渲染,使用useContext在改變一個數(shù)據(jù)時,是通過自己逐級查找對比改變的數(shù)據(jù)然后渲染,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-11-11
解決React報錯Expected?`onClick`?listener?to?be?a?function
這篇文章主要為大家介紹了React報錯Expected?`onClick`?listener?to?be?a?function解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12
webpack 2.x配置reactjs基本開發(fā)環(huán)境詳解
本篇文章主要介紹了webpack 2.x配置reactjs基本開發(fā)環(huán)境詳解,具有一定的參考價值,有興趣的可以了解一下2017-08-08
React?antd中setFieldsValu的簡便使用示例代碼
form.setFieldsValue是antd?Form組件中的一個方法,用于動態(tài)設(shè)置表單字段的值,它接受一個對象作為參數(shù),對象的鍵是表單字段的名稱,值是要設(shè)置的字段值,這篇文章主要介紹了React?antd中setFieldsValu的簡便使用,需要的朋友可以參考下2023-08-08

