Skip to main content

cs4140 Notes: 19 React

··2 mins

Let’s set up React and a React component for PartyAnimal

cd assets
corepack enable pnpm
pnpm add react
pnpm add flowbite-react

Update tailwind config to look in jsx files:

module.exports = {
  content: [
    "./js/**/*.js",
    "./js/**/*.jsx",  // Here

In app.js:

import "./invites/main";

In invites/main.jsx:

import React from 'react';
import { createRoot } from 'react-dom/client';

import Invites from './invites';

const root_div = document.getElementById('invites-main');
if (root_div) {
  const root = createRoot(root_div);
  root.render(<Invites />);
}

In invites/invites.jsx:

import React from 'react';
import { createRoot } from 'react-dom/client';

import { Card } from 'flowbite-react';

export default function Invites(props) {
  return (
    <div className="flex items-center justify-center">
      <Card className="max-w-sm">
        <p>Invites go here</p>
      </Card>
    </div>
  );
}

In …/page_html/home.html.heex:

  <div id="invites-main">
    React component loading...
  </div>

In invites/api.js:

const base = "/ajax/invites";

export async function list_invites() {
  let resp = await fetch(base, {
    headers: {
      'Accept': 'application/json',
    }
  });
  return await resp.json();
}

And now update invites.jsx:

import { list_invites } from './api';

export default function Invites(props) {
  const [invites, setInvites] = useState([]);

  useEffect(() => {
    list_invites().then((xs) => setInvites(xs));
  }, []);

  console.log(invites);
  let invite_items = invites.map((item, ii) => (
    <li key={ii}>
      { item.name }
    </li>
  ));

  return (
    <div className="flex items-center justify-center">
      <Card className="max-w-sm">
        <ul>
          { invite_items }
        </ul>
      </Card>
    </div>
  );
}

Digression: Phoenix UI #

We don’t need to push to React just to get already styled UI components: