Styled Components

Styled Components is a 3rd party library for creating components with built in css.

  • install npm install styled-components

Use like so...

import styled from "styled-components"

const Container = styled.div`
  width: 80%;
  margin: auto;
  text-align: center;
`

const Title = styled.h1`
  font-size: 3em;
  color: red;
`

const Component = props => (
  <Container>
    <Title>Hello World</Title>
  </Container>
)

Conditional Rendering

There are times when something should render in some situations and not in others. In frameworks like Vue, Angular and Svelte you have things like directives that directly add semantic ways to express this, React leans hard on using pure javascript to control the flow of a component (so strong Javascript skills really pay off in React).

In this article, we will look at an IsEven component that renders one thing if a prop is even and another it isn't. We'll show you different ways of express it.

Return statement within an if block

const IsEven = props => {
  if (props.number % 2 === 0) {
    return <h1> It is even </h1>
  } else {
    return <h1>It is odd</h1>
  }
}

Single Return Statement, If assigns value to a variable

const IsEven = props => {
  let result

  if (props.number % 2 === 0) {
    result = <h1> It is even </h1>
  } else {
    result = <h1>It is odd</h1>
  }

  return result
}

Returning a Ternary Operator

const IsEven = props => {
  return props.number % 2 === 0 ? <h1> it is even </h1> : <h1> it is odd </h1>
}

Returning a Ternary Operator but parts stored in variables

const IsEven = props => {
  const condition = props.number % 2 === 0

  const ifTrue = () => <h1> it is even </h1>

  const ifFalse = () => <h1> it is odd </h1>

  return condition ? ifTrue() : ifFalse()
}

Conditional Classes

const Modal = props => (
  <div className={props.visible ? "active" : ""}>{props.children}</div>
)
const Modal = props => {
  const divClass = props.visible ? "active" : ""

  return <div className={divClass}>{props.children}</div>
}

Conditional Styles

const Modal = props => (
  <div style={{ display: props.visible ? "block" : "none" }}>
    {props.children}
  </div>
)
const Modal = props => {
  const divDisplay = props.visible ? "block" : "none"

  return <div style={{ display: divDisplay }}>{props.children}</div>
}
const Modal = props => {
  const divStyle = {
    display: props.visible ? "block" : "none",
  }

  return <div style={divStyle}>{props.children}</div>
}

Using Object Keys to Determine JSX

const Component = props => {
  const result = {
    good: <h1>Good</h1>,
    bad: <h1>Bad</h1>,
    ugly: <h1>Ugly</h1>,
  }

  return result[props.key]
}

Using a Switch Statement

const Hello = (props) => {
  switch(props.language){
    case "eng":
      return <h1>Hello</h1>
    case "esp":
      return <h1>Hola</h1>
    default:
      return: <h1> No Language Detected </h1>
  }
}

Quick Tips

Destructuring Props

If you know the names of the props your component will receive you can destructure them and save you the hassle of typing props.

const Component = ({ name, age }) => (
  <div>
    <h1>{name}</h1>
    <h2>{age}</h2>
  </div>
)

Spreading Props

If you are giving a component a LOOOOOT of props and it may be a little messy to type them inline, then bundle them in an object and spread them.

So instead of...

<Component name="Arthur Bernier" age={35} website="deeperThanCode.com" />

Do this...

const props = {
    name: "Arthur Bernier",
    age: 35,
    website: "deeperThanCode.com"
}

return <Component {...props}>

props.children

All component have a prop by default called "children", the children prop represent any wrapped in the components opening and closing tag. So imagine the below we have a Container Component we use to block of content.

const Container = (props) => {
  const style = {
    width: "90%",
    margin: "auto,
    border: "1px solid green"
  }
  return <div style={style}> {props.children} </div>
}

const App = (props) => {
  return <Container><h1>Hello World</h1></Container>
}

In this case anything between the opening and closing Container tag are stored in props.children will render inside of a div with a green border.

Portals

Portals are a way of injecting something somewhere else in the DOM, not used very often but here is an example.

import { createPortal } from "react"

// This component renders div with the id of target
const Target = props => {
  return <div id="target"></div>
}

// regardless of where this component is used, the h1 will be rendered inside of an element that has the id of "target"
const Payload = props => {
  return createPortal(
    <h1>This is a weird place to be</h1>,
    document.querySelector("#target")
  )
}

const App = () => (
  <>
    <Target />
    <Payload />
  </>
)

So even though the Payload component is below Target, it's output will appear within Target since we are mounting Payload to the div Target renders.

  • react-router & react-router-dom (client side router)
  • Formik (forms)
  • Styled Components (Styling)
  • Reactstap and React Bootstrap (different bootstrap implementations)
  • MaterialUI (Material Design Implementation)
  • merced-react-hooks (Several Custom Hooks for API calls, Forms, State Management, etc.)
  • Redux (state management)
  • NextJS (Server-Side Rendering and Static Generation)
  • Gatasby (Static Site Generator)
  • ReactNative (Mobile Development)

Other Frontend Frameworks (Competitors)

  • Angular
  • Vue
  • Svelte
  • SolidJS (Write JSX that compiles like Svelte)
  • StencilJS (Create Web Components with JSX)
  • litHTML/litElement (Web Components)
  • AMPonent (Web Components)
  • KofuJS (Opinionated Class Based Library with JSX and Observables)
  • Ember

Copyright © Per Scholas 2023