<html>
<head>
<title>This is the title of the webpage!</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
</body>
</html>
const useHandler = (handler) => React.useRef(handler).current;
function useHandlerComponent() {
const testFunction = useHandler(evt => evt.preventDefault(), []);
return React.createElement('button', {
onClick: testFunction
}, 'Test click');
}
function UseCallbackComponent() {
const testFunction = React.useCallback(evt => evt.preventDefault(), []);
return React.createElement('button', {
onClick: testFunction
}, 'Test click');
}
ReactDOM.render(React.createElement(useHandlerComponent), document.getElementById('root'))
ReactDOM.render(React.createElement(UseCallbackComponent), document.getElementById('root'))
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
ComponentWithOuterFunctionUseCallback | |
ComponentWithUseCallback |
Test name | Executions per second |
---|---|
ComponentWithOuterFunctionUseCallback | 1005868.0 Ops/sec |
ComponentWithUseCallback | 993201.9 Ops/sec |
The provided benchmark compares two approaches in React for defining event handler functions: using a custom hook (useHandler
) and using the built-in React useCallback
hook. Here’s a breakdown of what’s tested, the pros and cons of each approach, and relevant considerations.
Custom Hook Approach (useHandler
):
useHandler
that uses React.useRef
to maintain a reference to the event handler function. The handler is updated through the handler
parameter of the custom hook.useHandlerComponent
ReactDOM.render(React.createElement(useHandlerComponent), document.getElementById('root'))
Built-in Hook Approach (useCallback
):
React.useCallback
hook to memoize the event handler function. It returns a memoized version of the callback that only changes if one of the dependencies has changed.UseCallbackComponent
ReactDOM.render(React.createElement(UseCallbackComponent), document.getElementById('root'))
useHandler
)Pros:
Cons:
useCallback
)Pros:
Cons:
Library Usage: This benchmark relies on React (version 18.2.0) and React DOM for creating components and rendering them onto the webpage. The purpose of these libraries is to build user interfaces by allowing developers to define UI components that can efficiently update and render in response to data changes.
Testing Environment: The benchmark runs in Chrome 133 on a Mac, measuring the number of executions per second of the different components. This helps to evaluate the performance implications of using one method over the other in a real-world scenario.
There are several other approaches that could be considered:
componentDidMount
and shouldComponentUpdate
) can be used to control rendering behavior and update handlers as needed.Understanding when to use each approach is key to optimizing performance and maintainability in React applications. Each method has its use cases, and a thoughtful choice depends on specific components or application architecture.