React is incredibly powerful, but mastering it means going beyond the basics and learning some lesser-known tricks to streamline development. Here’s a rundown of my personal favourite 20 React tricks that can boost your productivity and help you write cleaner, more effective code. Let’s dive straight into examples!
Avoid verbose if statements for conditional rendering with short-circuit evaluation.
{isLoading && <Spinner />}
This renders the
The classnames library makes it easy to conditionally apply classes.
npm install classnames
import classNames from 'classnames'; const buttonClass = classNames({ 'btn': true, 'btn-primary': isPrimary, 'btn-secondary': !isPrimary, }); <button className={buttonClass}>Click Me</button>
If a computation is costly, memoize it so React doesn’t recompute unnecessarily.
const sortedData = useMemo(() => data.sort(), [data]);
This recalculates sortedData only when data changes.
Avoid constant re-renders by debouncing input changes.
const [value, setValue] = useState(''); const [debouncedValue, setDebouncedValue] = useState(''); useEffect(() => { const handler = setTimeout(() => setDebouncedValue(value), 500); return () => clearTimeout(handler); }, [value]); <input value={value} onChange={(e) => setValue(e.target.value)} />
Encapsulate logic in a custom hook to reuse it across components.
function useFetch(url) { const [data, setData] = useState(null); useEffect(() => { fetch(url).then(res => res.json()).then(setData); }, [url]); return data; } const Component = () => { const data = useFetch('/api/data'); return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>; };
Optimize loading time by splitting your components.
const LazyComponent = React.lazy(() => import('./LazyComponent')); function App() { return ( <React.Suspense fallback={<div>Loading...</div>}> <LazyComponent /> </React.Suspense> ); }
To access previous state values, use useRef.
const [count, setCount] = useState(0); const prevCount = useRef(count); useEffect(() => { prevCount.current = count; }, [count]); console.log(`Previous: ${prevCount.current}, Current: ${count}`);
If a function doesn’t need to change, memoize it with useCallback.
const increment = useCallback(() => setCount(count + 1), [count]);
Destructure props right in the function parameters.
const User = ({ name, age }) => ( <div>{name} is {age} years old</div> );
Wrap elements without adding an extra DOM node.
<> <p>Paragraph 1</p> <p>Paragraph 2</p> </>
Catch errors in child components to prevent the whole app from crashing.
class ErrorBoundary extends React.Component { state = { hasError: false }; static getDerivedStateFromError() { return { hasError: true }; } render() { if (this.state.hasError) return <h1>Something went wrong.</h1>; return this.props.children; } }
Catch bugs early by defining prop types.
{isLoading && <Spinner />}
For complex state logic, useReducer can be more efficient.
npm install classnames
Run effects after DOM updates but before paint.
import classNames from 'classnames'; const buttonClass = classNames({ 'btn': true, 'btn-primary': isPrimary, 'btn-secondary': !isPrimary, }); <button className={buttonClass}>Click Me</button>
Create global state without prop drilling.
const sortedData = useMemo(() => data.sort(), [data]);
Defining functions inline causes re-renders. Instead, define them outside.
const [value, setValue] = useState(''); const [debouncedValue, setDebouncedValue] = useState(''); useEffect(() => { const handler = setTimeout(() => setDebouncedValue(value), 500); return () => clearTimeout(handler); }, [value]); <input value={value} onChange={(e) => setValue(e.target.value)} />
Handle null or undefined values gracefully.
function useFetch(url) { const [data, setData] = useState(null); useEffect(() => { fetch(url).then(res => res.json()).then(setData); }, [url]); return data; } const Component = () => { const data = useFetch('/api/data'); return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>; };
Always use unique keys when rendering lists.
const LazyComponent = React.lazy(() => import('./LazyComponent')); function App() { return ( <React.Suspense fallback={<div>Loading...</div>}> <LazyComponent /> </React.Suspense> ); }
Named exports make importing specific components easier.
const [count, setCount] = useState(0); const prevCount = useRef(count); useEffect(() => { prevCount.current = count; }, [count]); console.log(`Previous: ${prevCount.current}, Current: ${count}`);
Then import as needed:
const increment = useCallback(() => setCount(count + 1), [count]);
Wrap components with HOCs to add extra logic.
const User = ({ name, age }) => ( <div>{name} is {age} years old</div> );
Mastering these tricks will help you write more concise, readable, and efficient React code! Happy coding!
The above is the detailed content of Essential React Tricks Every Developer Must Know. For more information, please follow other related articles on the PHP Chinese website!