ReactJS with TypeScript

# 参考動画
https://youtu.be/SqcY0GlETPk

# Directory structure

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/ca86b8b8-176d-2886-37e3-d5f87da65082.png)


# Props with String, Array and Function
```javascript:App.js

    import "./App.css";
    import Alert from "./components/Alert";
    import Button from "./components/Button";
    import ListGroup from "./components/ListGroup";
    import { useState } from "react";
    
    const App = () => {
      let items = ["New York", "Tokyo", "Paris", "San Fransisco"];
    
      const [alertVisible, setAlertVisibility] = useState(false);
    
      const handleSelectItem = (item: string) => {
        console.log(item);
      };
      return (
        <div>
          {alertVisible && (
            <Alert onClose={() => setAlertVisibility(false)}>
              Hello World <span>!!</span>
            </Alert>
          )}
          <ListGroup
            items={items}
            heading="Cities"
            onSelectItem={handleSelectItem}
          />
          <Button
            color="primary"
            onClick={() => {
              console.log("Clicked");
              setAlertVisibility(true);
            }}
          >
            My Button
          </Button>
        </div>
      );
    };
    
    export default App;

```



```javascript:ListGroup.tsx
    import { useState } from "react";
    
    interface Props {
      items: string[];
      heading: string;
      onSelectItem: (item: string) => void;
    }
    
    const ListGroup = ({ items, heading, onSelectItem }: Props) => {
      const [selectedIndex, setSelectedIndex] = useState(-1);
    
      return (
        <>
          <h1>{heading}</h1>
          {items.length === 0 && <p>No item found</p>}
    
          <ul className="list-group">
            {items.map((item, index) => (
              <li
                key={item}
                className={
                  selectedIndex === index
                    ? "list-group-item active"
                    : "list-group-item"
                }
                onClick={() => {
                  setSelectedIndex(index);
                  onSelectItem(item);
                }}
              >
                {item}
              </li>
            ))}
          </ul>
        </>
      );
    };
    
    export default ListGroup;

```


```javascript:Alert.tsx

    import { ReactNode } from "react";
    
    interface Props {
      //   children: string;
      children: ReactNode;
      onClose: () => void;
    }
    
    const Alert = ({ children, onClose }: Props) => {
      return (
        <div className="alert alert-primary alert-dismissible">
          {children}
          <button
            type="button"
            className="btn-close"
            onClick={onClose}
            data-bs-dismiss="alert"
          ></button>
        </div>
      );
    };
    
    export default Alert;


```

```javascript:Button.tsx

    interface Props {
      children: string;
      color?: "primary"| "secondary"| "danger";
      onClick: () => void;
    }
    
    const Button = ({ children, onClick, color = "primary" }: Props) => {
      return (
        <button className={"btn btn-" + color} onClick={onClick}>
          {children}
        </button>
      );
    };
    
    export default Button;


```