You have quite a few problems.
- You should do your best to avoid
any
in TypeScript, especially not liberally - that defeats the whole purpose of type-checking. If you're trying to fix type problems, you should start by also typing everything properly.
- Arrow functions do not have their
this
altered by the calling context. If there's no enclosing full-fledged function
, the this
in an arrow function will be the global object or undefined
, both of which are useless to you. Either use a function
to capture the this
, or, even better, use the click event's currentTarget to get a reference to the clicked button.
- The
.innerHTML
of an element returns a string, not an element. If it contains a string that can be coerced to a number, explicitly coerce it to a number instead. (If the HTML content is only the string that can be coerced to the number, you should use .textContent
instead - only use .innerHTML
when deliberately setting or retrieving HTML markup, not plain text)
- A better approach would be to pass down the
i
to onSquareClick
instead of using DOM manipulation - using the closure is much easier
let i = 1;
export const Square = ({ onClick }: { onClick: () => void }) => {
i += 1;
if (i > 100) {
i = 1;
}
return (
<DefaultButton styles={factionMapButton} onClick={(e) => { onSquareClick(i, onClick); }}>{i}</DefaultButton>
);
};
const onSquareClick = (number: number, isOpen: () => void) => {
const panelContent = document.getElementById('panelContent');
if (panelContent !== null) {
panelContent.innerHTML = String(number);
}
isOpen();
};
- If you're using React, you should not be using vanilla DOM manipulation like
panelContent.innerHTML = number;
- instead, set React state that the view uses to determine what should exist in that element. Something like
// Parent component:
const [panelContentText, setPanelContentText] = useState('');
// expand as needed for the other components in your app...
return <div id="panelContent">{panelContentText}</div>
<Square setPanelContentText={setPanelContentText} /* and other props */ />
// ...
// Then call the setPanelContentText prop in onSquareClick
const onSquareClick = (number: number, isOpen: () => void, setPanelContentText: React.Dispatch<React.SetStateAction<string>>) => {
setPanelContentText(String(number));
isOpen();
};
I'd recommend looking into an introductory React tutorial, it looks like you might benefit from learning the process within React's ecosystem, rather than trying to mishmash your understanding of vanilla JS's DOM with React.