Issue
The issue here is that the React ref is mutating the DOM, but React isn't made aware of this and so Component isn't rerendered with a working button allowing the onClick event to go through. This is the main reason why direct DOM manipulations are considered anti-pattern in React.
Additionally, you are setting a timeout to occur every render, though this would have minimal effect it's still unnecessary and would be considered an unintentional side-effect.
Solution
Use component state and update state in a mounting useEffect hook to trigger a rerender.
const Component = () => { const [isDisabled, setIsDisabled] = useState(true); useEffect(() => { setTimeout(() => { setIsDisabled(false); }, 1000); }, []); const handleClick = () => console.log('clicked'); return ( <div> <button onClick={handleClick} disabled={isDisabled}>click me</button> </div> ) }
const Component = () => { const [isDisabled, setIsDisabled] = React.useState(true); React.useEffect(() => { setTimeout(() => { setIsDisabled(false); }, 1000); }, []); const handleClick = () => console.log('clicked'); return ( <div> <button onClick={handleClick} disabled={isDisabled}>click me</button> </div> ) }; ReactDOM.render( <Component />, document.getElementById("root") );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script> <div id="root"></div>