# React
###### tags: `React`, `js`
### Start a project
```bash
npx create-react-app project_name
```
* [use bootstrap in React](https://www.pluralsight.com/guides/how-to-use-bootstrap-components-with-reactjs)
* https://www.youtube.com/watch?v=3J-bSecBdj8&t=193s
### [JSX](https://reactjs.org/docs/introducing-jsx.html)
a logic-ui mixed expression
```jsx
const element = <h1>Hello, world!</h1>;
const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;
```
### Component
html:
```htmlembedded
<div id="root"></div>
```
js:
```jsx
function Welcome(props) {
return <h1>Hello, {props.name} {props.a}</h1>;
}
const element = <Welcome name="Sara" a="hsu"/>;
ReactDOM.render(element, document.getElementById('root'));
```
> Hello, Sara hsu [color=green]
:::warning
##### what happened above?
1. We call `ReactDOM.render()` with the `<Welcome name="Sara" />` element.
2. React calls the `Welcome` component with `{name: 'Sara'}` as the props.
:::
### Converting a Function to a Class
```jsx
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.props.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
```
### [States and lifecycles](https://reactjs.org/docs/state-and-lifecycle.html)
* `componentDidMount()` method runs after the component output has been rendered to the DOM. (a :+1: place to set up)
* `componentWillUnmount()` method is called when a component is being removed from the DOM
```jsx
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
```
### HandleEvents
Method 1
```jsx
// (add these in constructor)
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
handleClick() {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
```
Method 2
```jsx
class LoggingButton extends React.Component {
handleClick = () => {
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
```
Method 3
```jsx
class LoggingButton extends React.Component {
handleClick() {
console.log('this is:', this);
}
render() {
// This syntax ensures `this` is bound within handleClick
return (
<button onClick={(e) => this.handleClick(e)}>
Click me
</button>
);
}
}
```
Passing attributes:
```jsx
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
```
### Conditional Rendering
* `true && expression` = expression
* `false && expression` = false (invisible)
```jsx
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
</div>
<!-- Inline condition -->
<div>
{isLoggedIn ? (
<LogoutButton onClick={this.handleLogoutClick} />
) : (
<LoginButton onClick={this.handleLoginClick} />
)}
</div>
```
### List & Key
* `key`: a special string attribute you need to include when creating lists of elements
```jsx
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
return (
<ul>{listItems}</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
```