---
category: examples
group: component
title: cell custom component
cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/custom-cell-layout-jsx.png
order: 1-1
link: '../guide/custom_define/react-custom-component'
---
# cell custom component
Like customLayout, you can use react components to customize layout. For details, please refer to [Custom Components](../guide/custom_define/react-custom-component)
## code demo
```javascript livedemo template=vtable-react
// import * as ReactVTable from '@visactor/react-vtable';
const VGroup = ReactVTable.Group;
const VText = ReactVTable.Text;
const VImage = ReactVTable.Image;
const VTag = ReactVTable.Tag;
const records = [
{
bloggerId: 1,
bloggerName: 'Virtual Anchor Xiaohua',
bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/flower.jpg',
introduction:
'Hi everyone, I am Xiaohua, the virtual host. I am a little fairy who likes games, animation and food. I hope to share happy moments with you through live broadcast.',
fansCount: 400,
worksCount: 10,
viewCount: 5,
city: 'Dream City',
tags: ['game', 'anime', 'food']
},
{
bloggerId: 2,
bloggerName: 'Virtual anchor little wolf',
bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/wolf.jpg',
introduction:
'Hello everyone, I am the virtual anchor Little Wolf. I like music, travel and photography, and I hope to explore the beauty of the world with you through live broadcast.',
fansCount: 800,
worksCount: 20,
viewCount: 15,
city: 'City of Music',
tags: ['music', 'travel', 'photography']
},
{
bloggerId: 3,
bloggerName: 'Virtual anchor bunny',
bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/rabbit.jpg',
introduction:
'Hello everyone, I am the virtual anchor Xiaotu. I like painting, handicrafts and beauty makeup. I hope to share creativity and fashion with you through live broadcast.',
fansCount: 600,
worksCount: 15,
viewCount: 10,
city: 'City of Art',
tags: ['painting', 'handmade', 'beauty makeup']
},
{
bloggerId: 4,
bloggerName: 'Virtual anchor kitten',
bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/cat.jpg',
introduction:
'Hello everyone, I am the virtual host Kitty. I am a lazy cat who likes dancing, fitness and cooking. I hope to live a healthy and happy life with everyone through the live broadcast.',
fansCount: 1000,
worksCount: 30,
viewCount: 20,
city: 'Health City',
tags: ['dance', 'fitness', 'cooking']
},
{
bloggerId: 5,
bloggerName: 'Virtual anchor Bear',
bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/bear.jpg',
introduction:
'Hello everyone, I am the virtual host Xiaoxiong. A little wise man who likes movies, reading and philosophy, I hope to explore the meaning of life with you through live broadcast.',
fansCount: 1200,
worksCount: 25,
viewCount: 18,
city: 'City of Wisdom',
tags: ['Movie', 'Literature']
},
{
bloggerId: 6,
bloggerName: 'Virtual anchor bird',
bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/bird.jpeg',
introduction:
'Hello everyone, I am the virtual anchor Xiaoniao. I like singing, acting and variety shows. I hope to be happy with everyone through the live broadcast.',
fansCount: 900,
worksCount: 12,
viewCount: 8,
city: 'Happy City',
tags: ['music', 'performance', 'variety']
}
];
const CustomLayoutComponent = (props) => {
const { table, row, col, rect, text } = props;
if (!table || row === undefined || col === undefined) {
return null;
}
const { height, width } = rect || table.getCellRect(col, row);
const record = table.getRecordByRowCol(col, row);
const [hoverTitle, setHoverTitle] = React.useState(false);
const [hoverIcon, setHoverIcon] = React.useState(false);
const groupRef = React.useRef(null);
return (
{
setHoverTitle(true);
event.currentTarget.stage.renderNextFrame();
}}
onMouseLeave={(event) => {
setHoverTitle(false);
event.currentTarget.stage.renderNextFrame();
}}
>
',
boundsPadding: [0, 0, 0, 10],
cursor: 'pointer',
background: hoverIcon ? {
fill: '#ccc',
cornerRadius: 5,
expandX: 1,
expandY: 1
} : undefined
}}
onMouseEnter={event => {
setHoverIcon(true);
event.currentTarget.stage.renderNextFrame();
}}
onMouseLeave={event => {
setHoverIcon(false);
event.currentTarget.stage.renderNextFrame();
}}
>
{record.tags.length
? record.tags.map((str, i) => (
//
{str}
))
: null}
);
}
const root = ReactDom.createRoot(document.getElementById(CONTAINER_ID));
root.render(
);
// release openinula instance, do not copy
window.customRelease = () => {
root.unmount();
};
```