There are a lot of typos or bugs in the code that you've posted:
- Missing
extends React.Component
.
- Missing
return
in render()
.
- Calling
this.clicked()
instead of passing a function to onClick
.
- Not checking that
link
isn't null
before assigning to it.
- Not calling
e.preventDefault()
on the click event to prevent rerendering to "#".
You could fix all of those errors and it would mostly work, but if the component re-renders for any reason then the the href
will go back to "#"
because that is what's set in the render()
.
class SomeComponent extends React.Component {
public ref: React.RefObject<HTMLAnchorElement>;
constructor(props: {}) {
super(props);
this.ref = React.createRef();
}
render() {
return (
<a href="#" ref={this.ref} onClick={this.clicked}>
Anchor Text
</a>
);
}
private clicked = (e: React.MouseEvent) => {
const link = this.ref.current;
if (link && link.href === "#" ) {
e.preventDefault();
link.href = "some_link";
}
};
}
Just Use State
It doesn't make any sense to modify the href
through DOM manipulation when you are the one who is setting the href
in the first place. Store the current value of the href
in this.state
and render your link with href={this.state.href}
.
We still need to conditionally call e.preventDefault()
only when href
is "#"
so this is still a weird design that can be improved. Maybe show a div
until its clicked an an a
after? But per your requirements, this will work:
class SomeComponent extends React.Component<{}, { href: string }> {
constructor(props: {}) {
super(props);
this.state = {
href: "#"
};
}
render() {
return (
<a href={this.state.href} onClick={this.clicked}>
Anchor Text
</a>
);
}
private clicked = (e: React.MouseEvent) => {
if ( this.state.href === "#" ) {
e.preventDefault();
this.setState({ href: "some_link" });
}
};
}