(ง •̀_•́)ง Ming's blog

React(1/2)

References

Cover topics

Introduction

React, popularized by Facebook, is an open-source JavaScript library for building user interfaces. It is used to create components, handle state and props, utilize event listeners and certain life cycle methods to update data as it changes. React combines HTML with JavaScript functionality to create its own markup language, JSX.

JSX

JSX is a convenient tool to write readable HTML within JavaScript.

//---It must return a single element.
const JSX = <h1>Hello JSX!</h1>;

const JSX = (
 <div>
  <h1>I am a h1</h1>
  {/*This is a comment*/}
  <p>I am a p</p>
  <ul>
   <li>we</li>
   <li>are</li>
   <li>li-s</li>
  </ul>
 </div>
);

//---naming convention for all HTML attributes and event references in JSX become camelCase.
const JSX = (
 <div className="myDiv">
  {/*use className instead of class, because it is a reserve word in JS*/}
  <h1>Add a class to this div</h1>
 </div>
);

//---self-closing JSX tag
//<br> must be written as <br />
//<div></div> can also be written as <div />, but will not be able to include things between
const JSX = (
 <div>
  <h2>Welcome to React!</h2> <br />
  <p>Be sure to close all tags!</p>
  <hr />
 </div>
);

//---With React, we can render this JSX directly to the HTML DOM using React's rendering API known as ReactDOM.
//format: ReactDOM.render(componentToRender, targetNode);
ReactDOM.render(JSX, document.getElementById("root")); //call after JSX element declaration

Component

React components are the core building blocks of React applications.

Component architecture React provides allows you to compose your UI from many separate, isolated components. This makes it easier to build and maintain complex user interfaces.

//---There are 2 way to create a React component.

//---1.stateless functional component: create component with a JS function

// After being transpiled, the <div> will have a CSS class of 'customClass'
const DemoComponent = function() {
 //React requires your function name to begin with a capital letter.
 return (
  <div className="customClass" /> //returns either JSX or null
 );
};

//---2.ES6 class syntax

//Kitten class now has access to many useful React features, such as local state and lifecycle hooks.
class Kitten extends React.Component {
 //Kitten extends React.Component
 //constructor is a special method used during the initialization of objects that are created with the class keyword
 constructor(props) {
  super(props); // super is used to call the constructor of the parent class, in this case React.Component
 }

 //It is best practice to call a component's constructor with super, and pass props to both. This makes sure the component is initialized properly

 render() {
  return <h1>Hi</h1>;
 }
}

//---Component with Composition
const TypesOfFruit = () => {
 //children of Fruits
 return (
  <div>
   <h2>Fruits:</h2>
   <ul>
    <li>Apples</li>
    <li>Blueberries</li>
    <li>Strawberries</li>
    <li>Bananas</li>
   </ul>
  </div>
 );
};

const Fruits = () => {
 //parent of TypesOfFruit
 return (
  <div>
   <TypesOfFruit />
  </div>
 );
};

class TypesOfFood extends React.Component {
 //parent of Fruits
 constructor(props) {
  super(props);
 }

 render() {
  return (
   <div>
    <h1>Types of Food:</h1>
    <Fruits />
   </div>
  );
 }
}

//---Render a Class component to the DOM
//format: ReactDOM.render(<ComponentToRender />, targetNode)
ReactDOM.render(<TypesOfFood />, document.getElementById("challenge-node"));

Props

In React, you can pass props, or properties, to child components.

//App component renders a child component called Welcome that is a stateless functional component.
<App>
 <Welcome user="Mark" />
</App>;

//You use custom HTML attributes that React provides support for to pass the property user to the component Welcome.
const Welcome = props => <h1>Hello, {props.user}!</h1>;

//---passing array as props
const List = props => {
 return <p>{props.tasks.join(", ")}</p>;
};

class ToDo extends React.Component {
 constructor(props) {
  super(props);
 }
 render() {
  return (
   <div>
    <h1>To Do Lists</h1>
    <h2>Today</h2>
    <List tasks={["walk dog", "workout"]} />
    <h2>Tomorrow</h2>
    <List tasks={["walk dog", "workout", "grocery"]} />
   </div>
  );
 }
}

//---default props
MyComponent.defaultProps = { location: "San Francisco" };

//---override default
const Items = props => {
 return <h1>Current Quantity of Items in Cart: {props.quantity}</h1>;
};

Items.defaultProps = {
 quantity: 0
};

class ShoppingCart extends React.Component {
 constructor(props) {
  super(props);
 }
 render() {
  return <Items quantity={10} />;
 }
}

//---Define expected props type
MyComponent.propTypes = { handleClick: PropTypes.func.isRequired };

//---Note: As of React v15.5.0, PropTypes is imported independently from React, like this:
import React, { PropTypes } from "react";

//---use this keyword in ES6 class
class ReturnTempPassword extends React.Component {
 constructor(props) {
  super(props);
 }
 render() {
  return (
   <div>
    <p>
     Your temporary password is: <strong>{this.props.tempPassword}</strong>
    </p>
   </div>
  );
 }
}

class ResetPassword extends React.Component {
 constructor(props) {
  super(props);
 }
 render() {
  return (
   <div>
    <h2>Reset Password</h2>
    <h3>We've generated a new temporary password for you.</h3>
    <h3>Please reset this password from your account settings ASAP.</h3>
    <ReturnTempPassword tempPassword="12345678" />
   </div>
  );
 }
}

State

State is one of the most powerful features of components in React. It consists of any data your application needs to know about, that can change over time and allows you to track important data in your app and render a UI in response to changes in this data.

//---Note that you must create a class component by extending React.Component in order to create state like this.
class StatefulComponent extends React.Component {
 constructor(props) {
  super(props);
  // initialize state here
  this.state = { name: "Ming" };
 }
 render() {
  return (
   <div>
    <h1>{this.state.name}</h1>
   </div>
  );
 }
}

//another way to render state in the UI
class MyComponent extends React.Component {
 constructor(props) {
  super(props);
  this.state = {
   name: "freeCodeCamp"
  };
 }
 render() {
  const name = this.state.name;
  return (
   <div>
    <h1>{name}</h1>
   </div>
  );
 }
}

//---set state: React expects you to never modify state directly, instead always use this.setState() when state changes occur.
//toggle element
class MyComponent extends React.Component {
 constructor(props) {
  super(props);
  this.state = {
   visibility: false
  };
  this.toggleVisibility = this.toggleVisibility.bind(this); //bind this to class method
 }
 toggleVisibility() {
  if (this.state.visibility) {
   this.setState({
    visibility: false
   });
  } else {
   this.setState({
    visibility: true
   });
  }
 }
 render() {
  if (this.state.visibility) {
   return (
    <div>
     <button onClick={this.toggleVisibility}>Click Me</button>
     <h1>Now you see me!</h1>
    </div>
   );
  } else {
   return (
    <div>
     <button onClick={this.toggleVisibility}>Click Me</button>
    </div>
   );
  }
 }
}

//counter
class Counter extends React.Component {
 constructor(props) {
  super(props);
  this.state = {
   count: 0
  };
  this.increment = this.increment.bind(this);
  this.decrement = this.decrement.bind(this);
  this.reset = this.reset.bind(this);
 }
 increment() {
  this.setState({
   count: this.state.count + 1
  });
 }

 decrement() {
  this.setState({
   count: this.state.count - 1
  });
 }

 reset() {
  this.setState({
   count: 0
  });
 }
 render() {
  return (
   <div>
    <button className="inc" onClick={this.increment}>
     Increment!
    </button>
    <button className="dec" onClick={this.decrement}>
     Decrement!
    </button>
    <button className="reset" onClick={this.reset}>
     Reset
    </button>
    <h1>Current Count: {this.state.count}</h1>
   </div>
  );
 }
}

//---controlled form
class MyForm extends React.Component {
 constructor(props) {
  super(props);
  this.state = {
   input: "",
   submit: ""
  };
  this.handleChange = this.handleChange.bind(this);
  this.handleSubmit = this.handleSubmit.bind(this);
 }
 handleChange(event) {
  this.setState({
   input: event.target.value
  });
 }
 handleSubmit(event) {
  this.setState({
   input: "",
   submit: this.state.input
  });
 }
 render() {
  return (
   <div>
    <form onSubmit={this.handleSubmit}>
     <input value={this.state.input} onChange={this.handleChange} />
     <button type="submit">Submit!</button>
    </form>
    <h1>{this.state.submit}</h1>
   </div>
  );
 }
}

//---Pass State as Props to Child Components
//Paradigms in React:
//unidirectional data flow
//complex stateful apps can be broken down into just a few, or maybe a single, stateful component.
class MyApp extends React.Component {
 constructor(props) {
  super(props);
  this.state = {
   name: "CamperBot"
  };
 }
 render() {
  return (
   <div>
    <Navbar name={this.state.name} />
   </div>
  );
 }
}

class Navbar extends React.Component {
 constructor(props) {
  super(props);
 }
 render() {
  return (
   <div>
    <h1>Hello, my name is: {this.props.name}</h1>
   </div>
  );
 }
}

//---pass a callback as props
class MyApp extends React.Component {
 constructor(props) {
  super(props);
  this.state = {
   inputValue: ""
  };
  this.handleChange = this.handleChange.bind(this);
 }
 handleChange(event) {
  this.setState({
   inputValue: event.target.value
  });
 }
 render() {
  return (
   <div>
    <GetInput input={this.state.inputValue} handleChange={this.handleChange} />
    <RenderInput input={this.state.inputValue} />
   </div>
  );
 }
}

class GetInput extends React.Component {
 constructor(props) {
  super(props);
 }
 render() {
  return (
   <div>
    <h3>Get Input:</h3>
    <input value={this.props.input} onChange={this.props.handleChange} />
   </div>
  );
 }
}

class RenderInput extends React.Component {
 constructor(props) {
  super(props);
 }
 render() {
  return (
   <div>
    <h3>Input Render:</h3>
    <p>{this.props.input}</p>
   </div>
  );
 }
}