Difficulty: Beginner
A functional component in React is simply a JavaScript function that returns JSX. It is the primary and recommended way to create components in modern React. Before hooks were introduced in React 16.8, class components were needed for stateful logic, but today functional components can do everything class components can and more.
To create a functional component, you write a regular JavaScript function (or arrow function) that accepts a single argument - the props object - and returns JSX. The function name must start with a capital letter. This is not just a convention; React uses the casing to distinguish between DOM elements (lowercase like `div`, `span`) and custom components (PascalCase like `App`, `UserProfile`). If you name a component starting with a lowercase letter, React will treat it as an HTML tag.
There are two common patterns for defining components: function declarations and arrow function expressions. Function declarations use the `function` keyword and are hoisted, meaning they can be referenced before they are defined in the file. Arrow function expressions are assigned to a `const` and are not hoisted, but they offer a more concise syntax. Both are perfectly valid, and teams typically pick one style and stick with it.
Exporting components follows standard JavaScript module patterns. You can use a default export (`export default function App()`) or a named export (`export function App()`). Default exports allow the consumer to name the import whatever they want, while named exports enforce consistent naming. Many React projects prefer named exports because they work better with auto-imports and refactoring tools. A file can have one default export and multiple named exports.
A component must return something that React can render: JSX elements, strings, numbers, booleans, null, or arrays of these. Returning `null` tells React to render nothing. A component should be a pure function of its props - given the same props, it should always return the same output. Side effects should be handled in event handlers or useEffect hooks, not during rendering.
// Function declaration style
function Welcome(props) {
return { type: 'h1', props: { children: 'Hello, ' + props.name } };
}
// Arrow function style
const Greeting = (props) => {
return { type: 'p', props: { children: 'Welcome back, ' + props.name } };
};
// Using the components (simulated)
const el1 = Welcome({ name: 'Alice' });
const el2 = Greeting({ name: 'Bob' });
console.log(el1.props.children);
console.log(el2.props.children);
Both function declarations and arrow functions work as React components. The component receives props as its first argument and returns a React element.
// Component names MUST start with uppercase
function UserCard(props) {
const fullName = props.firstName + ' ' + props.lastName;
return {
type: 'div',
props: {
className: 'user-card',
children: fullName + ' (Age: ' + props.age + ')'
}
};
}
// Components are just functions - you can call them
const result = UserCard({ firstName: 'Jane', lastName: 'Doe', age: 30 });
console.log(result.props.children);
console.log(result.props.className);
PascalCase naming is required for React components. The component is just a function that takes an object of props and returns an element description.
// Simulating different export patterns
// Pattern 1: Default export
// export default function App() { return <div>App</div>; }
// Pattern 2: Named export
// export function Header() { return <header>Header</header>; }
// Pattern 3: Export separately
// function Footer() { return <footer>Footer</footer>; }
// export { Footer };
// Demonstrating that components are just functions
const components = {
App: () => ({ type: 'div', props: { children: 'App' } }),
Header: () => ({ type: 'header', props: { children: 'Header' } }),
Footer: () => ({ type: 'footer', props: { children: 'Footer' } })
};
Object.keys(components).forEach(name => {
const el = components[name]();
console.log(name + ': ' + el.type + ' -> ' + el.props.children);
});
Components can be exported as default or named exports. Named exports are often preferred for better IDE support and consistent imports.
functional components, component creation, naming conventions, export patterns, component return values