As functional React components is more modern with support to hooks which is useful, it’s common practice to rewrite the old styled class components to functional components. This article summarizes some common steps and pitfalls for the transformation.
Common Replacements
Definition
From
1 | class (\w+) extends Component \{ |
To
1 | const $1: FC = () => { |
- It’s for situation without
exportandprops.
From
1 | (export) default class (\w+) extends Component \{ |
To
1 | $1 const $2: FC<$2Props> = () => { |
- As the second captured word,
$2is the component name. $2Propsshould be defined as the name ofpropsinterface.
Attributes Prefix
From
1 | this\.(state\.|props\.)? |
To
1 |
- Assume that
propsis destructed uniformly.
Lift Cycle functions
From
1 | componentDidMount() { |
To
1 | useEffect(() => {}, []); |
componentDidUpdatecan also be transformed touseEffect, with appropriate dependencies.componentWillUnmountcan be transformed to return function of correspondinguseEffecthandler.
State Related Statement
From
1 | state = { |
To
1 | const [data, setData] = useState(); |
From
1 | this.setState({ |
To
1 | setData(data) |
Class Methods
From
1 | ^(\s*)(\w+)\((\w*)\) \{ |
To
1 | $1const $2 = ($3) => { |
- It’s for regular function definition.
$1is white spaces,$2is method name,$3is parameters
From
1 | ^(\s*)((\w+) = (async )?\((\w+(, )?)*\) =>) |
To
1 | $1const $2 |
- It’s for arrow function definition.
$1is white spaces,$2is everything from the method name.
Class Getter
From
1 | ^(\s*)(get) (\w+)\(\) |
To
1 | $1const $2\u$3 = () => |
\umeans capitalizing the following captured word.- The invoking of the getter should have
()after the name. - If the getter is simple, it can be assign directly without function.
Render function
From
1 | render() { |
To
1 | return ( |
Notable Pitfalls
Name Conflict
It’s possible for class component to have the same name as attributes and props, such as this.data and this.props.data.
With this.data become data, and it’s common to destruct props as const {data} = props, the name conflict comes.
State Callback
With this.setState, we can set a callback to be invoked after the state is changed actually, but we have to change this implementation to useEffect with the changed state as dependency.
Function as State
If the value of a state is a function, you wrap it into an anonymous function or else the hook version of setState will treat it as a callback.
Actually, in most case, this kind of state is not related to rendering, so perhaps useRef is more suitable for them.
This article shows some replacement with RegExp, which will make the transformation from class to functional component easier, and some pitfalls that you may encounter during the process for you to pay attention to, but to be sure, there can be more jobs for different scenarios.