JSX Components

JSX Components

JSX is syntax sugar for React.createElement calls. Once you internalize that, a lot of “weird JSX rules” stop being weird.

What is a react element? is an object version of the element for going from jsx to converting from react element to the dom element in the browser react components return a react element, then to html elements in the browser

What JSX compiles to

This:

const el = <button onClick={handleClick}>Click me</button>;

…compiles to roughly this:

const el = React.createElement('button', { onClick: handleClick }, 'Click me');

That’s why JSX expressions can only have one root element — a function call returns one value.

// definition
function add (x, y) {
  return * + y
} 


// invocation
add (1, 2) n


// component definition
function Icon () {
  return ‹svg />
} 

// an element, not a component or component element, jsx function turns the component into html element
<Icon /> 

Handling events

// Do: will be executed when the click event occurs
<button onClick={handleClick}>
Passing a Reference
</button>

// Don't: will continually call the function
<button onClick={handleClick()}>
Passing an Invocation
</button>

Expressions vs. statements

Inside { ... } in JSX you can put any expression, but not a statement.

function Greeting({ user }) {
  return (
    <p>
      Hello, {user ? user.name : 'stranger'}.
    </p>
  );
}

if, for, and switch are statements — they can’t go inside { }. Use ternaries, &&, or extract a helper.

Lists

<ul>
  {items.map((item) => (
    <li key={item.id}>{item.label}</li>
  ))}
</ul>

The key prop is React’s identity hint for reconciliation. Use a stable id, not the array index.

Props

Props is how we pass data into a child component, typically.

function Hello (props) {
  return <h1>Hello, {props.name}</h1>
}

export default function App () {
  return <Hello name='Tyler' />
}

One thing to note is that if you pass a prop without a value, that value will be set to true. These are equivalent.

Use destructuring:

function Hello ({ first, last }) {
  return (
    <h1>
      Hello, {first} {last}
    </h1>
  )
}
<Profile
  username="tylermcginnis"
  authed={true}
  logout={handleLogout}
  header={<h1>👋</h1>}
/>

An object:

<DatePicker settings={{
  format: "yy-mm-dd",
  animate: false,
  days: "abbreviate"
}} />

Children

<Header>You can have text between tags.</Header>

<Layout>
  <h1>You can also have</h1>
  <p>elements between tags</p>
</Layout>
function Header (props) {
  return <h1 className="header">{props.children}</h1>
}

function Layout (props) {
  return (
    <div className="layout">
      <Sidebar />
      {props.children}
      <Footer />
    </div>
  )
}
export default function App () {
  const [isOpen, setIsOpen] = React.useState(false)

  const handleOpen = () => setIsOpen(true)
  const handleClose = () => setIsOpen(false)
  
  return (
    <main>
      <button onClick={handleOpen}>Open Modal</button>
      {isOpen && (
        <Modal onClose={handleClose}>
          <h1>Modal is Customizable</h1>
          <p><i>children</i> can be whatever we want.</p>
          <p>(and it can be different each time we use Modal)</p>
        </Modal>
      )}
    </main>
  )
}