373 <Button
374 variant='primary'
375 className={classes.resultsBtn}
376 onClick={() => setOpened(false)}377 loading={isFetching}
378 >
379 {t('view-x-result', { count: resultCount })}
375 </Group>
376 </Modal>
377
378 <Box ref={ref} component={DefaultLauncher} onClick={() => setOpened(true)} {...props} />379 </>
380 )
381 }
375 </Group>
376 </Modal>
377
378 <Box ref={ref} component={DefaultLauncher} onClick={() => setOpened(true)} {...props} />379 </>
380 )
381 }
367 <Button
368 variant='primary'
369 className={classes.resultsBtn}
370 onClick={() => setOpened(false)}371 loading={isFetching}
372 >
373 {t('view-x-result', { count: resultCount })}
358 <Group className={modalClasses.footer} noWrap>
359 <Button
360 variant='secondary'
361 onClick={() => deselectAll()}362 disabled={selectedItems.length < 1}
363 className={classes.uncheckBtn}
364 >
334 <>
335 <Modal
336 opened={opened}
337 onClose={() => setOpened(false)}338 title={<TitleBar modalTitle />}
339 fullScreen={isMobile}
340 classNames={modalClasses}
310 {modalTitle ? (
311 <Text
312 fw={500}
313 onClick={() => deselectAll()}314 className={selectedItems.length > 0 ? classes.uncheck : classes.uncheckDisabled}
315 >
316 {t('uncheck-all')}
33 return (
34 <Group position='apart' align='center' noWrap>
35 <Box maw='70%' style={{ overflow: 'hidden' }}>
36 <Breadcrumb onClick={() => closeAllModals()} {...breadcrumb} />37 </Box>
38 {rightSection}
39 </Group>
179 <Loader size={32} mr={16} />
180 </Group>
181 ) : form.values.search.length > 0 ? (
182 <Group spacing={4} noWrap className={classes.rightIcon} onClick={() => form.reset()}>183 <Text>{t('clear')}</Text>
184 <Icon icon='carbon:close' />
185 </Group>
113 classNames={{ root: classes.root, icon: classes.icon }}
114 px={`calc(${theme.spacing.sm} - ${rem(2)})`}
115 py={theme.spacing.xs}
116 onClick={clickHandler}117 leftIcon={<Icon icon={iconRender} height={24} color={theme.other.colors.secondary.black} />}
118 >
119 <Text size='md' fw={theme.other.fontWeight.semibold} truncate>
Using .bind()
or passing local callback functions as props to react component incurs a performance overhead.
Consider using React.useCallback
, or if possible, moving the callback definition outside the component.
EXCEPTIONS: This rule may not apply if your react component is only rendered once, or if your application is not performance sensitive. In such cases, consider adding a skipcq to prevent DeepSource from raising this issue on a single component. Alternatively, for small applications, you could add this issue in the ignore rules section.
Note that the performance overhead is not determined by the size of the callback function, but instead the number of times the component is rendered.
If the callback passed to a prop is local to the render function, it will get recreated every time the component renders.
This affects performance by causing unnecessary re-renders if a brand new function is passed as a property to a component that uses a reference equality check on the property to determine if it should update.
Using the useCallback
hook on functional components, or a method on class components is more performant.
Bad Practice
function CardWrapper() {
// the function `handleClick` is recreated every time
// a `CardWrapper` component is rendered.
const handleClick = (e) => displayCardDetails(e)
return <Card onClick={handleClick} />
}
function CardWrapper_() {
return <Card onClick={(e) => displayCardDetails(e)} />
}
class _CardWrapper extends React.Component {
render() {
return <Card onClick={(e) => displayCardDetails(e)} />
}
}
Recommended
function CardWrapper() {
// `handleClick` is no longer recreated on every render.
const handleClick = React.useCallback((e) => displayCardDetails(e))
return <Card onClick={handleClick} />
}
class CardWrapper_ extends React.Component {
handleClick(e) {
displayCardDetails(e)
}
render() {
return <Card onClick={this.handleClick} />
}
}