How to Refactor a Complex React Component for Easy Relocation
This article walks through a real‑world micro‑refactor of a React page, detailing the analysis of component dependencies, the step‑by‑step extraction of a tangled UI block into a reusable component, and the testing strategy that ensures the new code works without breaking existing functionality.
Requirement Background
A page needed a UI block (highlighted in red) moved to a new location, as shown in the before/after screenshot.
Requirement Evaluation
At first glance the task seemed trivial—just shift a component—but the existing code revealed hidden complexity. The page consists of components A and B . Component A contains sub‑components a1 and a2 , and the target position lies between them. The UI block to move, called b1 , lives inside B but is not a standalone component; it mixes two conditional components ( AR and HR ) and depends on ten properties from B 's context.
Refactor Purpose
Isolate the b1 logic into a movable component.
Improve code readability to lower the cost of understanding.
Preserve existing functionality.
Refactor Process
1. Make AR component independent
Original AR code inside B :
class ARecord extends React.Component {
openARecord = () => {
const openUrl = `${getBaseUrl()}#/list`;
openLink(openUrl);
};
render() {
return (
<div className="content" onClick={this.openARecord}>...</div>
);
}
}New, extracted AR component with explicit props:
// Interface for props
interface IARecordProps {
className?: string;
style?: object;
context: IContextModel;
componentProps: { id: string; pId: string };
}
export default function ARecord(props: IARecordProps) {
const { className, style = {}, context, componentProps } = props;
const { utSpace } = context;
const { id, pId } = componentProps;
const openARecord = (id: string, pId: string) => {
const openUrl = `${getBaseUrl()}#/arecordlist`;
openLink(openUrl);
};
return (
<div className="content" onClick={() => openARecord(id, pId)}>
...
</div>
);
}2. Page functional test
Added the new ARecord to the original location in B and verified the page behaved as before.
3. Encapsulate b1 as a new component
Defined data models:
// b1 data model
interface IHRecordSummaryData {
hasSupplySuite: () => boolean;
id: string;
pId: string;
type: TypeEnum;
data: {};
count: number;
name: string;
username: string;
code: string;
isUserInList: () => boolean;
}
// b1 component props
interface IHRecordSummaryProps {
className?: string;
style?: object;
context: IContextModel;
componentProps: IHRecordSummaryData;
}Implementation (simplified):
export default function HRecordSummary(props: IHRecordSummaryProps) {
const { context, componentProps } = props;
const { id, pId, type, data, count, name, username, code, hasSupplySuite, isUserInList } = componentProps || {};
const getComponentNode = (cp) => {
if (type === TypeENUM.REPAIR_CHECK && data && !hasSupplySuite) {
return <ARecord context={context} componentProps={{ id, pId }} />;
}
if (hasSupplySuite || type > 1) {
return (
<HRecord
pId={pId}
id={id}
count={count}
name={name}
username={username}
isLeave={type === TypeEnum.LEAVE}
code={code}
/>
);
}
if (!isUserInList || location.href.indexOf('list') !== -1) {
return null;
}
return null;
};
return <div>{getComponentNode(componentProps)}</div>;
}4. Reduce API surface
Combined the ten properties passed from Page → B → b1 into a single object, decreasing B 's API count from 37 to 29.
5. Simplify data handling
Replaced two method props with their boolean results and turned a large data object into a simple boolean flag, further shrinking the component contract.
6. Continuous testing
After each refactor step, functional tests were run and passed, ensuring no regression.
Conclusion
By extracting tangled logic into well‑defined, type‑safe components and consolidating APIs, the code became easier to understand, maintain, and relocate. The final test suite confirmed that the new structure works correctly, illustrating how even small daily requirements are opportunities for incremental code improvement.
"Any fool can write code that a computer understands; only a great programmer writes code that humans can understand." – Martin Fowler
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Alibaba Cloud Developer
Alibaba's official tech channel, featuring all of its technology innovations.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
