`, `38345019365308190000`)">
Copy
<body>
  <noscript> You need to enable JavaScript to run this app. </noscript>
  <div id="root"></div>

  <script type="text/javascript" src="./book-list/runtime.js"></script>
  <script type="text/javascript" src="./book-list/polyfills.js"></script>
  <script type="text/javascript" src="./book-list/main.js"></script>
</body>

Using the book list component

Now that we have everything in place, let’s start by modifying our app component and add a list of books as it’s state so we can pass it down to our book list:

Copy
constructor(props){
  super(props)
  this.state = {
    books: [
      {
        name: '10% Happier',
        description: `Practicing meditation and mindfulness
          will make you at least 10 percent happier.`
      },
      {
        name: 'The 10X Rule',
        description: `The biggest mistake most people
          make in life is not setting goals high enough.`
      },
      {
        name: 'A Short Guide to a Happy Life',
        description: `The only thing you have that nobody
          else has is control of your life.`
      }
    ]
  };
}

Now we can use our book list component and pass the books down as property:

Copy
render() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <h1 className="App-title">Welcome to React</h1>
      </header>

      <div className="book-list">
        <book-list ref={elem => this.nv = elem}
          books={JSON.stringify(this.state.books)}></book-list>
      </div>
      <div className="selected-books">
        <h1>Shopping card</h1>
        {this.renderSelectedBooks()}
      </div>
    </div>
  );
}
Note: As I mentioned above, we need to pass a string to our custom component or it won’t receive the correct data.

We used a method to render the selected books, so let’s define it:

Copy
renderSelectedBooks() {
    return(
      <div>
        {
          this.state.selectedBooks.map(function(book, index){
            return <div><strong key={ index }>{book.name}</strong></div>;
          })
        }
      </div>
    )
  }

I am using internal state here, but note that this is not a React post and I am not following any practice here.

Also we used a variable called nv to have a reference to the component. We will add an event listener to it which listens to bookSelected event and called a method to handle the event.

Copy
componentDidMount() {
  this.nv.addEventListener("bookSelected", this.handleBookSelected);
}
Warning: The name of the event should match the name of event that you used when defining the Angular element.

Let’s initialise our state in our event handler:

Copy
handleBookSelected = event => {
  const book = JSON.parse(event.detail)
  let selectedBookList = []

  if (this.state.selectedBooks.find(x => x.name === book.name)) {
    selectedBookList = this.state.selectedBooks.filter(
      x => x.name !== book.name
    )
  } else {
    selectedBookList = [...this.state.selectedBooks, book]
  }

  this.setState({
    ...this.state,
    selectedBooks: [...selectedBookList],
  })
}

The above code looks a bit busy, but it is very simple. We first check if the book is already selected and remove it if it is. If the book is not in selected list we add it and update the state. Once the state is updated React will reload the page and shows the updated selected books.

If you run the app now you should see a screen like this:

And that’s it you’re officially running an Angular element inside a React app and they get along really well 😁🔥💯.

You can find the source code on my GitHub repository.

Hope you’ve enjoyed the reading.

Support my work 👇🏽
Crypto