-1

I'm struggling to reference something on my webpage using this:

new Chessboard(document.getElementById('board3')

It is supposed to display the board, but instead I get this error:

Error: container element is null

The first answer in this link says...

This is most likely due to your script running before the page is loaded.

Why my `<div id="terminal-container">` is null?

So, how do I get around this issue where I need to create the board but I cannot do that because the id is in the return portion of the code, and so it is not yet created. I tried adding it after the return () code, but that did nothing!

Any ideas?

export const MyPiece = props => {

  new Chessboard(document.getElementById('board3'), {
    position:
      'rn2k1r1/ppp1pp1p/3p2p1/5bn1/P7/2N2B2/1PPPPP2/2BNK1RR w Gkq - 4 11',
    orientation: COLOR.black,
  });

  return (
    <>
        <DialogContent dividers>
        <Typography paragraph="true">
          Some text
        </Typography>
        <Paper id="board3"></Paper>
      </DialogContent>
    </>
  );
};
Jon
  • 167
  • 7

2 Answers2

2

This document.getElementById('board3') is executed before the first render. The node is not available jet. Also every time the component is updated this function will runs. I assume that you don't want that. I recommend you to move your code to useEffect block:

useEffect(()=> {
  new Chessboard(document.getElementById('board3'), {
    position:
      'rn2k1r1/ppp1pp1p/3p2p1/5bn1/P7/2N2B2/1PPPPP2/2BNK1RR w Gkq - 4 11',
    orientation: COLOR.black,
  });
}, []);

You can replace document.getElementById('board3') with useRef, It is the recommend way.

lissettdm
  • 7,119
  • 1
  • 4
  • 23
0

Cause new Chessboard(... run before <Paper id="board3"></Paper> is mounted. Try wrap it in the useEffect

import { useEffect } from 'react'

export const MyPiece = props => {

  useEffect(() => {
    new Chessboard(document.getElementById('board3'), {
      position:
      'rn2k1r1/ppp1pp1p/3p2p1/5bn1/P7/2N2B2/1PPPPP2/2BNK1RR w Gkq - 4 11',
      orientation: COLOR.black,
    });
  }, [])

  return (
    <>
        <DialogContent dividers>
        <Typography paragraph="true">
          Some text
        </Typography>
        <Paper id="board3"></Paper>
      </DialogContent>
    </>
  );
};

Or if you do not use react hooks, It could be

class MyPiece extends React.Component {

  componentDidMount() {
    new Chessboard(document.getElementById('board3'), {
       position:
       'rn2k1r1/ppp1pp1p/3p2p1/5bn1/P7/2N2B2/1PPPPP2/2BNK1RR w Gkq - 4 11',
       orientation: COLOR.black,
    });
  }

  render() {
    return (
      <>
        <DialogContent dividers>
        <Typography paragraph="true">
          Some text
        </Typography>
        <Paper id="board3"></Paper>
        </DialogContent>
      </>
    );
  }
}
Giang Le
  • 4,160
  • 1
  • 19
  • 20
  • Oh wow, that was perfect! Thank you. Your solution was so far off my radar I would have never got there without your help. I tried it and bingo, worked first time. I thought I was in a catch-22 situation. This will be very useful in lots of my stuff. Kind regards. – Jon May 18 '21 at 15:39