HTML Form Elements in React

import React, {useState} from "react";

function Info() {
    const [name, setName] = useState("");

    return (
        <div>
            <div>
                <label>
                    Name:
                    <input type="text" placeholder="Enter your name" value={name}
                           onChange={event => {
                               setName(event.target.value)
                           }}/>
                </label>

            </div>
            <div>
                Result : Hello {name}
            </div>

        </div>
    );
}

export default Info;

In most cases, it’s recommend using controlled components to implement forms. In a controlled component, form data is handled by a React component. The alternative is uncontrolled components, where form data is handled by the DOM itself.

To write an uncontrolled component, instead of writing an event handler for every state update, you can use a ref to get form values from the DOM.

References
https://reactjs.org/docs/forms.html
https://reactjs.org/docs/uncontrolled-components.html
https://reactjs.org/docs/refs-and-the-dom.html

Create Events for React Component

Counter.tsx

import {useState} from "react";

function Counter(props: CounterProp) {
    const [count, setCount] = useState(0)

    const buttonClicked = () => {
        setCount(prevState => {

            var result = prevState + 1;

            if (props.onCounterChanged != null) {
                props.onCounterChanged(result);
            }

            return result;
        })
    };

    return (
        <div>
            <div>Counter Value : {count}</div>
            <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
                    onClick={buttonClicked}>Next
            </button>
        </div>
    );
}

export interface CounterProp {
    onCounterChanged?: (value: number) => void;
}

export default Counter;

App.tsx

import React from 'react';
import Counter from "./components/Counter";

function App() {
    return (
        <div className={"px-1"}>
            <Counter onCounterChanged={(value => console.log(value))}></Counter>
        </div>

    );
}

export default App;

References
https://www.tutorialsteacher.com/typescript/typescript-interface
https://stackoverflow.com/questions/39713349/make-all-properties-within-a-typescript-interface-optional

Handling Events on React

import {useState} from "react";

function Counter() {
    const [count, setCount] = useState(0)

    const buttonClicked = () => {
        setCount(prevState => prevState + 1)
    };

    return (
        <div>
            <div>Counter Value : {count}</div>
            <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
                    onClick={buttonClicked}>Next
            </button>
        </div>
    );
}

export default Counter;

Passing Arguments to Event Handlers

import {useState} from "react";

function Counter() {
    const [count, setCount] = useState(0)

    const buttonClicked = (e: React.MouseEvent<HTMLButtonElement>) => {
        console.log(e);
        setCount(prevState => prevState + 1)
    };

    return (
        <div>
            <div>Counter Value : {count}</div>
            <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
                    onClick={(e) => buttonClicked(e)}>Next
            </button>
        </div>
    );
}

export default Counter;

Prevent default behavior

import {useState} from "react";

function Counter() {
    const [count, setCount] = useState(0)

    const buttonClicked = (e: React.MouseEvent<HTMLButtonElement>) => {
        if (e.cancelable)
        {
            e.preventDefault();
        }

        setCount(prevState => prevState + 1)
    };

    return (
        <div>
            <div>Counter Value : {count}</div>
            <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
                    onClick={(e) => buttonClicked(e)}>Next
            </button>
        </div>
    );
}

export default Counter;

The preventDefault() method cancels the event if it is cancelable, meaning that the default action that belongs to the event will not occur.

For example, this can be useful when:

  • Clicking on a “Submit” button, prevent it from submitting a form
  • Clicking on a link, prevent the link from following the URL

Note: Not all events are cancelable. Use the cancelable property to find out if an event is cancelable.

Note: The preventDefault() method does not prevent further propagation of an event through the DOM. Use the stopPropagation() method to handle this.

References
https://reactjs.org/docs/handling-events.html
https://www.w3schools.com/jsref/event_preventdefault.asp
https://stackoverflow.com/questions/32298064/preventdefault-not-working-in-on-input-function

Components and Props in React

Greeting.tsx

function Greeting(props:GreetingProps) {
    return (
        <p className="px-1 py-4 font-bold text-red-700">Hello {props.name}</p>
    );
}

export interface GreetingProps {
    name:string
}

export default Greeting;

App.tsx

import React from 'react';
import Greeting from "./components/Greeting";

function App() {
  return (
    <Greeting name={"Mahmood"}></Greeting>
  );
}

export default App;

References
https://reactjs.org/docs/components-and-props.html

Conditional Rendering in React JSX

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {    return <UserGreeting />;  }  return <GuestGreeting />;}

Inside return

function List() {
    const people = [
        {id: 1, name: "Mahmood", isAdmin: true},
        {id: 2, name: "Ali", isAdmin: false},
        {id: 3, name: "Javad", isAdmin: false}
    ];

    return (
        <ul>
            {people.map((value, index) => (
                value.isAdmin?(<li key={value.id}>{value.name}</li>):null
            ))}
        </ul>
    );
}

export default List;

Preventing Component from Rendering

function WarningBanner(props) {
  if (!props.warn) {    return null;  }
  return (
    <div className="warning">
      Warning!
    </div>
  );
}

References
https://reactjs.org/docs/conditional-rendering.html

Display Lists in React JSX

function List() {
    const people = [
        {id: 1, name: "Mahmood"},
        {id: 2, name: "Ali"},
        {id: 3, name: "Javad"}
    ];

    return (
        <ul>
            {people.map((value, index) => (
                <li key={value.id}>{value.name}</li>
            ))}
        </ul>
    );
}

export default List;

Keys help React identify which items have changed, are added, or are removed. The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. Most often you would use IDs from your data as keys.

When you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort.

References
https://reactjs.org/docs/lists-and-keys.html