#How to return a React component from innerHTML in Astro

8 messages · Page 1 of 1 (latest)

tacit kernel
#

This is my jsx file.

import React from "react";

function Testing(props){
    return (
        <div>
        <p>{props.title}</p>
        </div>
    )  
}

export default Testing;

This is my astro file.

<Layout>
<h1>Events</h1>
<div id="testing"></div>
<Layout />
<script>
const upcomingEvents = [{id:1, eventTitle: "Pokemon hunting"}, {id:2, eventTitle:"Korok hunting"}]
function test(){
  const displayTest = document.getElementById("testing");
  displayTest.innerHTML = upcomingEvents.map((data) => (`<Testing key= "${data.id} title= "${data.eventTitle}"/>`
  ));}
  test();
<script />
slender flickerBOT
#

Hi @tacit kernel. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

It seems like you're trying to use a React component in an Astro file. To do this, you need to import the React component in your Astro file and use it within the Astro markup. Here's how you can modify your Astro file to use the Testing component:

  1. First, install the official React integration for Astro by running npm install --save @astrojs/renderer-react.

  2. Update your astro.config.mjs file to include the React renderer:

export default {
  renderers: ['@astrojs/renderer-react'],
  // ...
};
  1. Modify your Astro file to import and use the Testing component:
---
import Testing from './Testing.jsx';
import Layout from './Layout.astro';
---

<Layout>
  <h1>Events</h1>
  <div id="testing">
    {upcomingEvents.map((data) => (
      <Testing key={data.id} title={data.eventTitle} />
    ))}
  </div>
</Layout>

In this example, I've removed the <script> block and used the Testing component directly within the Astro markup. This way, you can take advantage of Astro's features and render the React component as needed.

For more information on using React components in Astro, refer to the Framework Components section (https://docs.astro.build/en/core-concepts/framework-components#using-framework-components) and the React integration guide (https://docs.astro.build/en/guides/integrations-guide/react#getting-started).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

Astro Documentation

Learn how to use the @astrojs/react framework integration to extend component support in your Astro project.

Astro Documentation

Learn how to use React, Svelte, etc.

#

@tacit kernel kapa.ai is still learning and improving, please let us how it did by reacting below

tacit kernel
#

@slender flicker
I want to initially just map 4 components then when the button is pressed then map all of them.
So my initial code is this:

<Layout>
<div>
{upcomingEvents.slice(0,4).map((data) => (<UpcomingEvents 
                    key={data.id)
                    title={data.eventTitle}
                    />))}
</div>
<button id="see-more">See More</button>
</Layout>

<script>
function buttonPress(){
        pressed = !pressed;
        console.log("Clicked:", pressed);
        // renderUpcomingEvents();
    }
const seeMore = document.getElementById("see-more");
seeMore.addEventListener("click", buttonPress); 
</script>
slender flickerBOT
#

Let me check the knowledge base for you. One moment! :books:

#

To achieve the desired behavior, you can modify your Astro file to include a client-side script that updates the displayed events when the "See More" button is clicked. Here's an updated version of your Astro file:

---
import UpcomingEvents from './UpcomingEvents.astro';
import Layout from './Layout.astro';
---

<Layout>
  <div id="events-container">
    {{upcomingEvents.slice(0, 4).map((data) => (
      <UpcomingEvents key={{data.id}} title={{data.eventTitle}} />
    ))}}
  </div>
  <button id="see-more">See More</button>
</Layout>

<script>
  let pressed = false;

  function buttonPress() {
    pressed = !pressed;
    console.log("Clicked:", pressed);

    const eventsContainer = document.getElementById("events-container");
    eventsContainer.innerHTML = '';

    const eventsToDisplay = pressed ? upcomingEvents : upcomingEvents.slice(0, 4);
    eventsToDisplay.forEach((data) => {
      const eventElement = document.createElement('astro-upcoming-events');
      eventElement.setAttribute('key', data.id);
      eventElement.setAttribute('title', data.eventTitle);
      eventsContainer.appendChild(eventElement);
    });
  }

  const seeMore = document.getElementById("see-more");
  seeMore.addEventListener("click", buttonPress);
</script>

In this example, I've updated the <script> block to clear the events-container and then create and append new astro-upcoming-events elements based on the pressed state. When the button is clicked, it toggles the pressed state and updates the displayed events accordingly.

Please note that this approach uses vanilla JavaScript to manipulate the DOM. If you prefer to use a UI framework like React, Vue, or Svelte, you can follow the respective integration guides in the Astro documentation:

#
Astro Documentation

Learn how to use the @astrojs/react framework integration to extend component support in your Astro project.

Astro Documentation

Learn how to use the @astrojs/vue framework integration to extend component support in your Astro project.

Astro Documentation

Learn how to use the @astrojs/svelte framework integration to extend component support in your Astro project.