Codecademy Logo

Refactoring React Applications Using AI

Related learning

  • Learn front-end development with AI tools. This course teaches you to build React applications using AI coding agents to speed up workflows.
    • Includes 2 Courses
    • With Certificate
    • Intermediate.
      6 hours

Refactoring React Applications

When refactoring React applications, split components when they handle multiple unrelated concerns or when parts become reusable. Each component should have a single, clear responsibility.

// Before: Doing too much
function UserProfile({ user }) {
return (
<div>
<img src={user.avatar} alt={user.name} />
<h2>{user.name}</h2>
<button>Follow</button>
<button>Message</button>
</div>
);
}
// After: Single responsibilities
function Avatar({ src, alt }) {
return <img src={src} alt={alt} />;
}
function UserProfile({ user }) {
return (
<div>
<Avatar src={user.avatar} alt={user.name} />
<h2>{user.name}</h2>
</div>
);
}

State Locations

State should live in the lowest common ancestor of all components that need it. If siblings need to share state, lift it to their parent. This ensures proper data flow through the component tree.

function TemperatureInput({ value, onChange }) {
return <input value={value} onChange={(e) => onChange(e.target.value)} />;
}
function Calculator() {
const [temp, setTemp] = useState('');
return (
<div>
<TemperatureInput value={temp} onChange={setTemp} />
<p>Temperature: {temp}°C</p>
</div>
);
}

Component Composition with the children prop

The children prop enables flexible wrapper components that provide structure without knowing their content in advance. This makes components more reusable and modular.

function Card({ children }) {
return <div className="card">{children}</div>;
}
// Usage: Same Card, different content
function App() {
return (
<div>
<Card>
<h3>Profile</h3>
<p>John Doe</p>
</Card>
<Card>
<h3>Settings</h3>
<button>Edit</button>
</Card>
</div>
);
}

Presentational and Container Components

A common programming pattern in React is to have presentational and container components. Container components contain business logic (methods) and handle state. Presentational components render that behavior and state to the user.

In the example code, CounterContainer is a container component and Counter is a presentational component.

class CounterContainer extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
this.increment = this.increment.bind(this);
}
increment() {
this.setState((oldState) => {
return { count: oldState.count + 1 };
});
}
render() {
return <Counter count={this.state.count} increment={this.increment} />;
}
}
class Counter extends React.Component {
render() {
return (
<div>
<p>The count is {this.props.count}.</p>
<button onClick={this.props.increment}>Add 1</button>
</div>
);
}
}

props.children

Every component’s props object has a property named children. Using props.children will return everything in between a component’s opening and closing JSX tags.

function List(props) {
return <ul>{props.children}</ul>;
}
// Usage:
<List>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</List>

React CSS Modules

CSS Modules provide a way to scope styles locally to individual React components by automatically transforming class names into unique identifiers at build time. This prevents unintended style conflicts across the application and eliminates the need for complex naming conventions.

By separating styles into dedicated module files, components maintain better organization and modularity. Each component’s styles remain isolated, making it easier to locate and maintain styling logic without worrying about class name collisions.

/* Button.module.css */
.button {
padding: 10px 20px;
background-color: blue;
color: white;
}
/* Button.js */
import styles from './Button.module.css';
function Button({ children }) {
return (
<button className={styles.button}>
{children}
</button>
);
}

Stateful and Stateless Components

In React, a stateful component is a component that holds some state. Stateless components, by contrast, have no state. Note that both types of components can use props.

In the example, there are two React components. The Store component is stateful and the Week component is stateless.

function Store() {
const [sell, setSell] = useState("anything");
return (
<div>
<h1>I'm selling {sell}.</h1>
<button onClick={() => setSell("books")}>Change Item</button>
</div>
);
}
function Week(props) {
return <h1>Today is {props.day}!</h1>;
}

Parent State Pattern

A common React programming pattern involves using stateful parent components to manage state and pass it down to stateless child components as props. This approach centralizes state management in the parent while keeping child components focused on presentation and rendering.

Stateless child components receive data and event handlers through props, making them simpler to test and reuse. The parent component controls the state logic and updates, while children display the data they receive. This separation of concerns creates a clear data flow and makes component responsibilities easier to understand.

// Stateless child
function BabyYoda(props) {
return <h2>I am {props.name}!</h2>;
}
// Stateful parent
function Yoda() {
const [name, setName] = useState("Toyoda");
return (
<div>
<BabyYoda name={name} />
<button onClick={() => setName("Grogu")}>Reveal True Name</button>
</div>
);
}

Passing State Change Functions as Props

If a React parent component defines a function that changes its state, that function can be passed to a child component and invoked within the child to update the parent’s state.

// Child component receives the function as a prop
function NameInput({ onNameChange, name }) {
return (
<div>
<input onChange={onNameChange} />
<p>{name}</p>
</div>
);
}
// Parent component owns state and passes down both state and setter function
function Name() {
const [name, setName] = useState('');
const handleNameChange = (e) => {
setName(e.target.value);
};
return <NameInput onNameChange={handleNameChange} name={name} />;
}

Learn more on Codecademy

  • Learn front-end development with AI tools. This course teaches you to build React applications using AI coding agents to speed up workflows.
    • Includes 2 Courses
    • With Certificate
    • Intermediate.
      6 hours