# 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') ); ```