Full Stack Development

Events

by Tomas Trescak t.trescak@westernsydney.edu.au

React Fundamentals

Event Handlers

  • React events wrap native HTML events for consistency.
  • We use them as <div onClick={handler}>
  • Handlers depend on useState hook
  • function handler() {...}
    <button onclick={handler}>+</button>
  • <button onClick={() => {...}}></button>
  • function handler(e: React.Event<>) {...}

Conditional Rendering

/

Click Handler

      import React, { useState, render, MouseEventHandler } from "react";

function FeedbackForm() {
  const [message, setMessage] = useState("");

  const click: MouseEventHandler<HTMLButtonElement> = 
    (e) => {
    setMessage("Thank you for your feedback!");
  };

  return (
    <div>
      <button onClick={click}>
        Submit Feedback
      </button>
      <p>{message}</p>
    </div>
  );
}

render(<FeedbackForm />)
    

Conditional Rendering

/

Click Handler

      import React, { render, useState } from "react";

function FeedbackForm() {
  const [message, setMessage] = useState("");

  return (
    <div>
      <button
        onClick={e => {
          setMessage("Thank you!");
        }}
      >
        Submit Feedback
      </button>
      <p>{message}</p>
    </div>
  );
}

render(<FeedbackForm />)
    

Conditional Rendering

/

Click Handler

    function Component() {
  return (
    <button onClick={e => {
        setMessage("Thank you!");
    }}>Submit</button>
  );
}
  
    function Component() {
  function click() {
    setMessage("Thank you!");
  }
  
  return (
    <button onClick={click}>
      Submit
    </button>
  );
}
  
Handler Functions
Arrow Functions

Forms

/

Uncontrolled Components

      import React, { useRef, render } from "react";

function UncontrolledForm() {
  const inputRef = useRef();

  const handleSubmit = () => {
    alert(`Input Value: ${
      inputRef.current.value
    }`);
  };

  return (
    <div>
      <label htmlFor="title">Title: </label>
      <input 
        id="title" 
        type="text" 
        ref={inputRef} 
      />
      <button onClick={handleSubmit}>
        Submit
      </button>
    </div>
  );
}

render(<UncontrolledForm />)
    

Forms

/

Controlled Components

      import React, { useRef, useState, render } from "react";

function ControlledForm() {
  
  const inputRef = useRef();

  const handleSubmit = () => {
    alert(`Input Value: ${
      inputRef.current.value
    }`);
  };

  return (
    <div>
      <h1>{inputRef.current?.value}</h1>
      <label htmlFor="title">Title: </label>
      <input 
        id="title" 
        type="text" 
        ref={inputRef} 




      />
      <button onClick={handleSubmit}>
        Submit
      </button>
    </div>
  );
}

render(<ControlledForm />)
    

Forms

/

Controlled Components

      import React, { useRef, useState, render } from "react";

function ControlledForm() {
  const [title, setTitle] = useState("");
  const [body, setBody] = useState("")

  return (
    <form>
      <label htmlFor="title">Title: </label>
      <input 
        id="title" type="text" 
        onChange={e => setTitle(
          e.currentTarget.value
        )}
      />
      <label htmlFor="title">Body </label>
      <textarea 
        id="body" 
        onChange={e => setBody(
          e.currentTarget.value
        )}
      />
    </form>
  );
}

render(<ControlledForm />)
    

Forms

/

Controlled Components

      import React, { useRef, useState, render } from "react";

function ControlledForm() {
  const [formState, setFormState] = useState({
    title: "",
    content: "",
  });

  // type: ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>
  const updateFormState = (e) => {
    setFormState({
      ...formState,
      [e.currentTarget.name]: e.currentTarget.value
    })
  };

  return (
    <form>
      <label htmlFor="title">Title: </label>
      <input 
        id="title" 
        name="title" 
        value={formState.title}
        onChange={updateFormState}
        type="text" 
      />
      <label htmlFor="title">Body </label>
      <textarea 
        id="body" 
        name="body"
        value={formState.title}
        onChange={updateFormState}
      />
    </form>
  );
}

render(<ControlledForm />)
    

Forms

/

Controlled Components

      import React, { useRef, useState, render } from "react";

function ControlledForm() {
  const [formState, setFormState] = useState({
    title: "",
    content: "",
  });

  // type: ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>
  const updateFormState = (e) => {
    setFormState({
      ...formState,
      [e.currentTarget.name]: e.currentTarget.value
    })
  };

  function register(name: string) {
    return {
      name,
      id: name,
      onChange: updateFormState,
      value: formState[name]
    }
  }

  return (
    <form>
      <label htmlFor="title">Title: </label>
      <input {...register("title")} type="text" />
      <label htmlFor="title">Body </label>
      <textarea {...register("body")} />

      <h2>Email Preview</h2>
      <fieldset>
        <legend>{formState.title}</legend>
        {formState.body}
      </fieldset>
    </form>
  );
}

render(<ControlledForm />)
    

Forms

/

Form Hook

      import React, { useRef, useState, render } from "react";

function useFormState<T>(initialState: T) {
  const [formState, setFormState] = useState(initialState);
  
  const updateFormState = (e) => {
    setFormState({
      ...formState,
      [e.currentTarget.name]: e.currentTarget.value
    })
  }

  return {
    formState,
    setFormState,
    updateFormState,
    register(name: string) {
      return {
        name,
        id: name,
        onChange: updateFormState,
        value: formState[name]
      }
    }
  }
}

function ControlledForm() {
  const { register, formState } = useFormState({
    title: "",
    content: "",
  });

  return (
    <form>
      <label htmlFor="title">Title: </label>
      <input {...register("title")} type="text" />
      <label htmlFor="title">Body </label>
      <textarea {...register("body")} />

      <h2>Email Preview</h2>
      <fieldset>
        <legend>{formState.title}</legend>
        {formState.body}
      </fieldset>
    </form>
  );
}

render(<ControlledForm />)
    

Forms

/

Checkboxes

      import React, { useRef, useState, render } from "react";

function ControlledForm() {
  const [terms, setTerms] = useState(false);

  return (
    <form>
      <label> 
        <input 
          
          type="checkbox"
          onChange={e => 
            setTerms(e.currentTarget.checked)
          }
        />
        Agree to T&C
      </label>
    </form>
  );
}

render(<ControlledForm />)
    

Forms

/

Radios

      import React, { useRef, useState, render } from "react";

const cars = ["bmw", "volvo", "trabant"]

function ControlledForm() {
  const [car, setCar] = useState("");

  return (
    <form>
      <label> 
        Dad's Car
      </label>
      <select 
        onChange={e => 
          setCar(e.currentTarget.value)
        }
      >
        <option value="">Please Select ...</option>
        <option value="bmw">bmw</option>
        <option value="volvo">volvo</option>
        <option value="trabant">trabant</option>
      </select>

      <label> 
        Mum's Car
      </label>
      <select 
        onChange={e => 
          setCar(e.currentTarget.value)
        }
      >
        <option value="">Please Select ...</option>
        {cars.map(c => (
          <option key={c} value={c}>{c}</option>
        ))}
      </select>
    </form>
  );
}

render(<ControlledForm />)
    

Forms

/

Radios

      import React, { useRef, useState, render } from "react";

function ControlledForm() {
  const [quiz, setQuiz] = useState({});

  const handler = (e) => setQuiz({
    ...quiz,
    [e.currentTarget.name]: e.value
  })

  return (
    <form>
      <h2>Quiz Question A</h2>
      <label>
        <input 
          type="radio"
          name="Q1" 
          value="a_a"
          onChange={handler} />
        Answer A
      </label>
      <label>
        <input 
          type="radio"
          name="Q1" 
          value="a_b"
          onChange={handler} />
        Answer B
      </label> 

      <h2>Quiz Question B</h2>
      <label>
        <input 
          type="radio"
          name="Q2" 
          value="a_a"
          onChange={handler} />
        Answer A
      </label>
      <label>
        <input 
          type="radio"
          name="Q2" 
          value="a_a"
          onChange={handler} />
        Answer B
      </label> 
    </form>
  );
}

render(<ControlledForm />)