Conditional rendering is how React shows different UI based on state or props. The most common idioms are the ternary expression {isLoggedIn ? <Dashboard /> : <Login />} and short-circuit rendering with logical AND, {hasError && <Error />}. An early return inside the component body is also valid and is the cleanest choice when a branch should short-circuit the rest of the render.
JSX requires a component to return a single root element. React Fragments let you group multiple elements without introducing an extra DOM node, using either <React.Fragment>...</React.Fragment> or the shorthand <>...</>. The shorthand is more concise but cannot accept the key prop, so the long form is required when rendering lists. Portals go further: ReactDOM.createPortal(child, domNode) renders a child into a different part of the DOM entirely, which is the standard technique for modals, tooltips, and popups that need to escape overflow: hidden or stacking-context constraints of a parent.
Error handling has its own dedicated primitive: the Error Boundary. An Error Boundary is a class component that implements static getDerivedStateFromError() and/or componentDidCatch() to catch JavaScript errors in its child tree during rendering and in lifecycle methods, then display a fallback UI instead of a broken screen. Functional components cannot be error boundaries today — there is no hook equivalent of those static and instance methods — so libraries like react-error-boundary provide convenient wrappers around the class implementation.
Lifecycle methods themselves are a class-component concept. componentDidMount, componentDidUpdate, and componentWillUnmount mark the mounting, updating, and unmounting phases. Functional components replicate them through useEffect: an effect with an empty dependency array fires once on mount, one with dependencies fires when those values change, and a returned cleanup function fires on unmount and before the next run. <React.StrictMode> is a development-only wrapper that double-invokes certain functions and surfaces unsafe lifecycle usage and deprecated APIs — a useful safety net that has no effect in production builds.