Commit 8a6ebbb7 by tungnq

TODO: Bổ sung hàm check render

parent 1f57d4df
......@@ -7,8 +7,6 @@ import {
Text,
Image,
} from 'react-native';
import R from '../assets/R';
const Button = props => {
const {
title,
......
import React, { useState, useEffect, useRef } from 'react';
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
......@@ -10,7 +10,7 @@ import {
import Icon from 'react-native-vector-icons/MaterialIcons';
import R from '../../assets/R';
const { width: screenWidth } = Dimensions.get('window');
const {width: screenWidth} = Dimensions.get('window');
/**
* Component TabView có thể tái sử dụng
......@@ -65,7 +65,9 @@ const TabViewComponent = ({
if (defaultActiveKey) {
const keyExists = data.some(item => item.key === defaultActiveKey);
if (!keyExists) {
console.warn(`TabView: defaultActiveKey "${defaultActiveKey}" không tìm thấy trong data. Sử dụng tab đầu tiên.`);
console.warn(
`TabView: defaultActiveKey "${defaultActiveKey}" không tìm thấy trong data. Sử dụng tab đầu tiên.`,
);
initialKey = data[0].key;
}
} else {
......@@ -84,7 +86,9 @@ const TabViewComponent = ({
const uniqueKeys = [...new Set(keys)];
if (keys.length !== uniqueKeys.length) {
console.warn('TabView: Phát hiện key trùng lặp trong mảng data. Có thể gây lỗi không mong muốn.');
console.warn(
'TabView: Phát hiện key trùng lặp trong mảng data. Có thể gây lỗi không mong muốn.',
);
}
}, [data]);
......@@ -107,13 +111,13 @@ const TabViewComponent = ({
animated: true,
});
},
() => {} // Callback khi đo thất bại
() => {}, // Callback khi đo thất bại
);
}
}, [activeKey, scrollable]);
// Xử lý khi người dùng nhấn vào tab
const handleTabPress = (item) => {
const handleTabPress = item => {
// Không làm gì nếu tab bị disabled
if (item.disabled) return;
......@@ -143,7 +147,7 @@ const TabViewComponent = ({
return (
<TouchableOpacity
key={item.key}
ref={ref => tabRefs.current[item.key] = ref} // Lưu ref để dùng cho auto scroll
ref={ref => (tabRefs.current[item.key] = ref)} // Lưu ref để dùng cho auto scroll
style={[
styles.tab, // Style cơ bản
tabStyle, // Style tùy chỉnh từ props
......@@ -153,8 +157,7 @@ const TabViewComponent = ({
]}
onPress={() => handleTabPress(item)}
disabled={isDisabled}
activeOpacity={0.7}
>
activeOpacity={0.7}>
<View style={styles.tabContent}>
{/* Hiển thị icon nếu có */}
{item.icon && (
......@@ -169,14 +172,13 @@ const TabViewComponent = ({
<Text
style={[
styles.tabText, // Style text cơ bản
{ color: isActive ? activeColor : inactiveColor}, // Dùng màu từ props
{color: isActive ? activeColor : inactiveColor}, // Dùng màu từ props
textStyle, // Style text tùy chỉnh
isActive && styles.activeTabText, // Style text khi active
isActive && activeTextStyle, // Style text active tùy chỉnh
isDisabled && styles.disabledTabText, // Style text khi disabled
]}
numberOfLines={1}
>
numberOfLines={1}>
{/* Ưu tiên label, sau đó title, name, cuối cùng là 'Tab' */}
{item.label || item.title || item.name || 'Tab'}
</Text>
......@@ -186,7 +188,7 @@ const TabViewComponent = ({
<View
style={[
styles.activeIndicator,
{ backgroundColor: activeIndicatorColor || activeColor } // Dùng màu từ props
{backgroundColor: activeIndicatorColor || activeColor}, // Dùng màu từ props
]}
/>
)}
......@@ -306,4 +308,4 @@ const styles = StyleSheet.create({
});
// Export component để sử dụng ở nơi khác
export default TabViewComponent;
export default React.memo(TabViewComponent);
import React from 'react';
import React, { useRef, useEffect } from 'react';
import {
Dimensions,
Platform,
......@@ -234,9 +234,8 @@ export const removeItemFromArr2 = (items, index) => {
return fill;
};
export const isValidEmail = (email) =>
email.length > 0 && /(.+)@(.+){2,}\.(.+){2,}/gmi.test(email);
export const isValidEmail = email =>
email.length > 0 && /(.+)@(.+){2,}\.(.+){2,}/gim.test(email);
export const removeItemFromArr = (items, index) => {
items.splice(index, 1);
......@@ -607,7 +606,7 @@ export const getMimeType = fileExt => {
};
//Calendar
export const parseMinutes = (timeStr) => {
export const parseMinutes = timeStr => {
if (!timeStr || typeof timeStr !== 'string') return 0;
const parts = timeStr.split(':');
if (parts.length !== 2) return 0;
......@@ -616,7 +615,7 @@ export const parseMinutes = (timeStr) => {
return h * 60 + m;
};
export const formatDateToString = (date) => {
export const formatDateToString = date => {
const y = date.getFullYear();
const m = String(date.getMonth() + 1).padStart(2, '0');
const d = String(date.getDate()).padStart(2, '0');
......@@ -652,7 +651,7 @@ export const layoutDayEvents = (events, hourHeight = 80) => {
let cur = null;
for (const ev of mapped) {
if (!cur || ev.start >= cur.maxEnd) {
cur = { id: groups.length, items: [ev], maxEnd: ev.end };
cur = {id: groups.length, items: [ev], maxEnd: ev.end};
groups.push(cur);
} else {
cur.items.push(ev);
......@@ -709,4 +708,19 @@ export const layoutDayEvents = (events, hourHeight = 80) => {
// Trả về theo thứ tự ban đầu để render ổn định
return out.sort((a, b) => a._idx - b._idx);
/**
* Hook đếm số lần render của một component
*/
};
export const useRenderCount = (name = 'Component') => {
const renderCount = useRef(0);
renderCount.current += 1;
useEffect(() => {
console.log(`${name} đã render ${renderCount.current} lần`);
});
return renderCount.current;
};
......@@ -176,6 +176,7 @@ const ListWorkView = props => {
const renderBody = () =>{
return (
<View style={styles.body}>
{renderTabView()}
{renderCard()}
<View style={styles.listContainer}>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment