--- 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(); }; ```