Jarmojo
Jarmojo

Reputation: 91

React rendering

I want display a lottery wheel on my hobby project. I found this package in npm 'lottery-wheel' and tried to install it and render it without any success.

I installed it with:

npm install lottery-wheel

I included it in the component-file:

import Wheel from 'lottery-wheel';

I want to render it within the div (id: 'wheel'):

    render() {
          const wheel = new Wheel({
            el: document.querySelector("#wheel"),
            data: [{
              text: 'apple',
              chance: 20
            }, {
              text: 'banana'
            }, {
              text: 'orange'
            }, {
              text: 'peach'
            }],
            onSuccess(data) {
              console.log(data.text);
            }
          });
    
        return (
                <div id="wheel">
                    {wheel}
                </div>
        );
    }

I don't know where to put this when I have a structure llike this ...

class Lottery extends Component {

}

I can simply get the correct element with document.querySelector("#wheel") but please educate me on a good practice to render components and subcomponents using this main structure (class extends Component) Thanks!

Upvotes: 0

Views: 82

Answers (2)

k-wasilewski
k-wasilewski

Reputation: 4653

It doesn't matter if it's a class or a functional component. In either you can and should place their sub-components in render() (after adequate import, of course).

In your particular case, your Wheel component needs to get an existing DOM element (el attribute) to be rendered into, and your #wheel element is rendered after the Wheel initialization and doesn't exist yet during. The issue is ordering of functions (unfortunately for you, render() always comes last).

The simple solutions here would be: a) create a #wheel element in your index.html (not recommended since it interferes with the main React concept of rendering the whole App into one div); b) initialize your Wheel in a componentDidMount() (if you don't know about React lifecycle, read about it - quite fundamental) or its hook equivalent - those are simply executed after render():

useEffect(() => {
    //your initialization here
}, []);

Upvotes: 1

Enjayy
Enjayy

Reputation: 1074

Try using a ref https://reactjs.org/docs/refs-and-the-dom.html

Something along the lines of

class Wheel extends React.Component {
  constructor(props) {
    super(props);
    this.wheelRef = React.createRef();
  }

  componentDidMount() {
    const wheel = new Wheel({
      el: this.wheelRef.current,
      data: [
        {
          text: 'apple',
          chance: 20,
        },
        {
          text: 'banana',
        },
        {
          text: 'orange',
        },
        {
          text: 'peach',
        },
      ],
      onSuccess(data) {
        console.log(data.text);
      },
    });
  }

  render() {
    return <div ref={this.wheelRef} />;
  }
}

export default Wheel;


// Other file 
import Wheel from '../wheel';


render () {
  return <Wheel />
}

Upvotes: 1

Related Questions