React 17 Default Props To Params

1.0.0Last update Nov 5, 2024
by@oleksiikukuruza

Example

This codemod turns X into Y. It also does Z. Note: this is a contrived example. Please modify it.

Before

import React from 'react';
import PropTypes from 'prop-types';
import { makeStyles, useTheme } from '@material-ui/styles';
import classNames from 'classnames';
import Button from '../../../../components/controls/Button';
import ButtonLoader from '../../../../components/loaders/ButtonLoader';
import makeStateElementName from '../../../../theme-editor/utils/makeStateElementName';
const useStyles = makeStyles((theme) => ({
stakeButton: ({ editorId }) => ({
width: '100%',
height: 40,
fontWeight: 600,
...theme[editorId],
}),
stakeButtonDisabled: ({ editorId }) => ({
...theme[`${makeStateElementName(editorId, 'disabled')}`],
}),
'@media (hover: hover)': {
stakeButtonDisabled: ({ editorId }) => ({
'&:hover': {
...theme[`${makeStateElementName(editorId, 'disabled')}`],
},
}),
},
loaderContainer: {
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
}));
const StakeInputButton = ({
onClick,
isDisabled,
children,
className,
isLoading,
dataEditorId,
}) => {
const classes = useStyles({ editorId: dataEditorId });
const theme = useTheme();
return ( <
Button elementClasses = {
{
default: classNames(classes.stakeButton, className),
disabled: classes.stakeButtonDisabled,
}
}
disabled = { isDisabled } onClick = { onClick } style = {
{
padding: 0,
}
}
dataEditorId = { dataEditorId } >
{
isLoading ? ( <
div className = { classes.loaderContainer } >
<
ButtonLoader color = { theme.brandButton.color }
/> <
/div>
) : (
children
)
} <
/Button>
);
};
StakeInputButton.propTypes = {
dataEditorId: PropTypes.string,
};
StakeInputButton.defaultProps = {
dataEditorId: 'betslipPlaceBetButton',
};
export default StakeInputButton;

After

import React from 'react';
import PropTypes from 'prop-types';
import { makeStyles, useTheme } from '@material-ui/styles';
import classNames from 'classnames';
import Button from '../../../../components/controls/Button';
import ButtonLoader from '../../../../components/loaders/ButtonLoader';
import makeStateElementName from '../../../../theme-editor/utils/makeStateElementName';
const useStyles = makeStyles((theme) => ({
stakeButton: ({ editorId }) => ({
width: '100%',
height: 40,
fontWeight: 600,
...theme[editorId],
}),
stakeButtonDisabled: ({ editorId }) => ({
...theme[`${makeStateElementName(editorId, 'disabled')}`],
}),
'@media (hover: hover)': {
stakeButtonDisabled: ({ editorId }) => ({
'&:hover': {
...theme[`${makeStateElementName(editorId, 'disabled')}`],
},
}),
},
loaderContainer: {
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
}));
const StakeInputButton = ({
onClick,
isDisabled,
children,
className,
isLoading,
dataEditorId = 'betslipPlaceBetButton',
}) => {
const classes = useStyles({ editorId: dataEditorId });
const theme = useTheme();
return ( <
Button elementClasses = {
{
default: classNames(classes.stakeButton, className),
disabled: classes.stakeButtonDisabled,
}
}
disabled = { isDisabled } onClick = { onClick } style = {
{
padding: 0,
}
}
dataEditorId = { dataEditorId } >
{
isLoading ? ( <
div className = { classes.loaderContainer } >
<
ButtonLoader color = { theme.brandButton.color }
/> <
/div>
) : (
children
)
} <
/Button>
);
};
StakeInputButton.propTypes = {
dataEditorId: PropTypes.string,
};
export default StakeInputButton;

,This codemod turns X into Y. It also does Z. Note: this is a contrived example. Please modify it.

Before

// In react 19 default props should be replaced with js default function parameters
import React from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { useTranslation } from 'react-i18next';
import { makeStyles } from '@material-ui/styles';
import classNames from 'classnames';
import Button from '../../../components/controls/Button';
import { selectors as betsSelectors } from '../../../redux/ducks/bets';
import useOfflineBooking from '../hooks/useOfflineBooking';
const useStyles = makeStyles({
bookingButton: {
width: '100%',
fontWeight: 600,
},
});
const BookingCodeBookButton = ({ className, dataEditorId }) => {
const { makeBooking } = useOfflineBooking();
const { t } = useTranslation();
const classes = useStyles();
const selectionsValid = useSelector(betsSelectors.selectSelectionsValid);
return ( <
Button className = { classNames(classes.bookingButton, className) } disabled = {!selectionsValid } onClick = {
() => (selectionsValid ? makeBooking() : null) } dataEditorId = { dataEditorId } >
{ t('Book') } <
/Button>
);
};
BookingCodeBookButton.propTypes = {
className: PropTypes.string,
dataEditorId: PropTypes.string,
};
BookingCodeBookButton.defaultProps = {
className: null,
dataEditorId: 'betslipShareButton',
};
export default BookingCodeBookButton;

After

import React from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { useTranslation } from 'react-i18next';
import { makeStyles } from '@material-ui/styles';
import classNames from 'classnames';
import Button from '../../../components/controls/Button';
import { selectors as betsSelectors } from '../../../redux/ducks/bets';
import useOfflineBooking from '../hooks/useOfflineBooking';
const useStyles = makeStyles({
bookingButton: {
width: '100%',
fontWeight: 600,
},
});
const BookingCodeBookButton = ({
className = null,
dataEditorId = 'betslipShareButton',
}) => {
const { makeBooking } = useOfflineBooking();
const { t } = useTranslation();
const classes = useStyles();
const selectionsValid = useSelector(betsSelectors.selectSelectionsValid);
return ( <
Button className = { classNames(classes.bookingButton, className) } disabled = {!selectionsValid } onClick = {
() => (selectionsValid ? makeBooking() : null) } dataEditorId = { dataEditorId } >
{ t('Book') } <
/Button>
);
};
BookingCodeBookButton.propTypes = {
className: PropTypes.string,
dataEditorId: PropTypes.string,
};
export default BookingCodeBookButton;

,This codemod turns X into Y. It also does Z. Note: this is a contrived example. Please modify it.

Before

// do not add new parameter if default props exist but is not defined in function parameters
import React from 'react';
import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next';
import { makeStyles, useTheme } from '@material-ui/styles';
import ButtonArrow from '../../../../components/controls/ButtonArrow';
import SliderPoints from '../../../../components/controls/SliderPoints';
import BetSlipBonusesSlider from '../../BetSlipBonusesSlider';
import BetSlipEmptyBlock from '../../BetSlipTable/BetSlipEmptyBlock';
const useStyles = makeStyles((theme) => ({
bonusesListContainer: {
background: theme.bonusPopup.background,
color: theme.bonusPopup.color,
paddingBottom: 20,
overflowY: 'auto',
boxSizing: 'border-box',
},
points: {
maxWidth: 200,
margin: '0 auto',
},
topLine: {
marginBottom: 8,
padding: '8px 16px',
},
betSlipEmptyBlock: {
minHeight: 275,
},
}));
const BetSlipBonusesListBase = ({
slides,
currentSlide,
setCurrentSlide,
onCloseButtonClick,
className,
maxHeight,
}) => {
const theme = useTheme();
const classes = useStyles();
const { t } = useTranslation();
const arrowButtonBackground = theme.bonusPopup.background;
return ( <
div className = { `${classes.bonusesListContainer} ${className}` } style = { { maxHeight } } >
<
div className = { classes.topLine } >
<
ButtonArrow backgroundColor = { arrowButtonBackground } label = { t('Back') } onClick = { onCloseButtonClick } size = { 32 } direction = 'left' /
>
<
/div> {
slides.length > 0 ? ( <
>
<
BetSlipBonusesSlider items = { slides } currentSlide = { currentSlide } setCurrentSlide = { setCurrentSlide }
/> {
!!slides.length && ( <
div className = { classes.points } >
<
SliderPoints count = { slides.length } activeIndex = { currentSlide } color = { theme.bonusPopup.color } activeColor = { theme.bonusPopup.color }
/> <
/div>
)
} <
/>
) : ( <
BetSlipEmptyBlock text = { t('No available Bonuses at this moment') } className = { classes.betSlipEmptyBlock }
/>
)
} <
/div>
);
};
BetSlipBonusesListBase.propTypes = {
className: PropTypes.string,
placeholder: PropTypes.string, // for widgets
showBonusesForBet: PropTypes.string,
toggleChooseBonusBlock: PropTypes.func.isRequired,
onUseBonus: PropTypes.func.isRequired,
onActivateBonus: PropTypes.func.isRequired,
availableBonusesIds: PropTypes.arrayOf(PropTypes.string),
bonuses: PropTypes.objectOf(PropTypes.shape({})).isRequired,
};
BetSlipBonusesListBase.defaultProps = {
placeholder: null,
className: null,
showBonusesForBet: null,
availableBonusesIds: null,
};
export default BetSlipBonusesListBase;

After

import React from 'react';
import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next';
import { makeStyles, useTheme } from '@material-ui/styles';
import ButtonArrow from '../../../../components/controls/ButtonArrow';
import SliderPoints from '../../../../components/controls/SliderPoints';
import BetSlipBonusesSlider from '../../BetSlipBonusesSlider';
import BetSlipEmptyBlock from '../../BetSlipTable/BetSlipEmptyBlock';
const useStyles = makeStyles((theme) => ({
bonusesListContainer: {
background: theme.bonusPopup.background,
color: theme.bonusPopup.color,
paddingBottom: 20,
overflowY: 'auto',
boxSizing: 'border-box',
},
points: {
maxWidth: 200,
margin: '0 auto',
},
topLine: {
marginBottom: 8,
padding: '8px 16px',
},
betSlipEmptyBlock: {
minHeight: 275,
},
}));
const BetSlipBonusesListBase = ({
slides,
currentSlide,
setCurrentSlide,
onCloseButtonClick,
className = null,
maxHeight,
}) => {
const theme = useTheme();
const classes = useStyles();
const { t } = useTranslation();
const arrowButtonBackground = theme.bonusPopup.background;
return ( <
div className = { `${classes.bonusesListContainer} ${className}` } style = { { maxHeight } } >
<
div className = { classes.topLine } >
<
ButtonArrow backgroundColor = { arrowButtonBackground } label = { t('Back') } onClick = { onCloseButtonClick } size = { 32 } direction = 'left' /
>
<
/div> {
slides.length > 0 ? ( <
>
<
BetSlipBonusesSlider items = { slides } currentSlide = { currentSlide } setCurrentSlide = { setCurrentSlide }
/> {
!!slides.length && ( <
div className = { classes.points } >
<
SliderPoints count = { slides.length } activeIndex = { currentSlide } color = { theme.bonusPopup.color } activeColor = { theme.bonusPopup.color }
/> <
/div>
)
} <
/>
) : ( <
BetSlipEmptyBlock text = { t('No available Bonuses at this moment') } className = { classes.betSlipEmptyBlock }
/>
)
} <
/div>
);
};
BetSlipBonusesListBase.propTypes = {
className: PropTypes.string,
placeholder: PropTypes.string, // for widgets
showBonusesForBet: PropTypes.string,
toggleChooseBonusBlock: PropTypes.func.isRequired,
onUseBonus: PropTypes.func.isRequired,
onActivateBonus: PropTypes.func.isRequired,
availableBonusesIds: PropTypes.arrayOf(PropTypes.string),
bonuses: PropTypes.objectOf(PropTypes.shape({})).isRequired,
};
export default BetSlipBonusesListBase;

Build custom codemods

Use AI-powered codemod studio and automate undifferentiated tasks for yourself, colleagues or the community

background illustrationGet Started Now