React.js - A Refresher

 1. What is React?

  • It's a Javascript library for building user interfaces that are shown in the browser
  • It's a browser side Javascript library running in browser
  • It started a huge ecosystem with other third-party packages forming a framwork
  • We use it to build the frontend of web applications
  • React does not run on a server, React does not communicate with databases
  • React build highly reactive modern user interfaces and do so by following a declarative approach(you define the results, not the steps that lead to the result)
  • React using components which are UI building blocks we can define, then we compose our user interface from these components
  • Every component also define what it should render, under which circumstance

2. React Component

  • React component can be one of two things, it can be a Javascript function which returns jsx or it can be a Javascript class that has a render method
  • Custom components can be used as jsx(JavaScript XML) as well,  they should start with a capital character in the file you use them as jsx
  • we can build up our application from small reusable components and compose our user interface with the help of such components

Class Component example:

class App extends React.Component {
  render() {
    return <h1 title="This works!">A React App!</h1>;
  }
}

Function Component example:

const App = () => {
  return <h1 title="This works!">A React App!</h1>;
};

3. Multiple Components

  • In React we split our app in components, components can compose by other components

Component in one file:

// App.js
import React from "react";
import "./App.css";

const App = () => {
  return (
    <div className="course-goals">
      <h2>Course Goals</h2>
      <ul className="goal-list">
        <li>Learn Javascript</li>
        <li>Learn React</li>
        <li>Learn Redux</li>
        <li>Help others in course Q&A</li>
      </ul>
    </div>
  );
};

export default App;

Component in separate file:

// ./components/GoalList.js
import React from "react";

//css are applied globally to your entire page
import "./GoalList.css";

const GoalList = () => {
  return (
    <ul className="goal-list">
      <li>Learn Javascript</li>
      <li>Learn React</li>
      <li>Learn Redux</li>
      <li>Help others in course Q&A</li>
    </ul>
  );
};

export default GoalList;

// ./App.js
import React from "react";

// component start with an uppercase character
import GoalList from "./components/GoalList";

// styles are always applied globally
import "./App.css";

const App = () => {
  return (
    <div className="course-goals">
      <h2>Course Goals</h2>
      <GoalList />
    </div>
  );
};

export default App;

4. Using Props to pass Data between Components

  • It really is the core philosophy of React to split your app into smaller pieces for of keeping your component small, focused and manageable
  • React can pass data from component to component with a concept called props, short for properties
  • You can define attributes which are these props on components, then passes data to that component with props
  • React use single opening and closing curly braces to merge jsx code with some Javascript expression

Component which pass data:

// ./App.js
import React from "react";

// component start with an uppercase character
import GoalList from "./components/GoalList";

// styles are always applied globally
import "./App.css";

const App = () => {
  const courseGoals = [
    { id: "cg1", text: "Learn Javascript" },
    { id: "cg2", text: "Learn React" },
    { id: "cg3", text: "Learn Redux" },
    { id: "cg4", text: "Help others in course Q&A" },
  ];
  return (
    <div className="course-goals">
      <h2>Course Goals</h2>
      <GoalList goals={courseGoals} />
    </div>
  );
};

export default App;

Component which receive data:

// ./components/GoalList.js
import React from "react";

//css are applied globally to your entire page
import "./GoalList.css";

const GoalList = (props) => {
  return (
    <ul className="goal-list">
      <li>{props.goals[0].text}</li>
      <li>{props.goals[1].text}</li>
      <li>{props.goals[2].text}</li>
      <li>{props.goals[3].text}</li>
    </ul>
  );
};

export default GoalList;

5. Rendering Lists of Data

  • We can output an array of data as jsx elements
  • Map array of Javascript objects to an array of jsx elements 
  • React is capable of outputting an array of Javascript elements

Render array of data in Component:

// ./components/GoalList.js
import React from "react";

//css are applied globally to your entire page
import "./GoalList.css";

const GoalList = (props) => {
  return (
    <ul className="goal-list">
      {props.goals.map((goal) => (
        <li key={goal.id}>{goal.text}</li>
      ))}
    </ul>
  );
};

export default GoalList;

6. Handling Events

  • Use form component to add new goals
  • Handle the submit event of the form, we can add event listeners to the form  by adding onSubmit prop
  • Not every event is supported on every element, the default HTML elements have it's own event, for example a form element the onSubmit event,  button element have onClick event
  • We have to pass a pointer to a function that should be triggered when event happens
  • The function will get an event object, an event parameter passed in automatically by React, for example we can call event.preventDefault(), which prevents the browser default of sending a request to some backend
  • We want to handle onSubmit here in Javascript on the frontend, in React application 
  • Build a handler function in funcional component to handle onSubmit event

Here is NewGoal component:

// ./components/NewGoal.js
import React from "react";
import "./NewGoal.css";

const NewGoal = () => {
  const addGoalHandler = (event) => {
    event.preventDefault();
    const newGoal = {
      id: Math.random().toString(),
      text: "A new goal!",
    };
    console.log("onSubmit trigger addGoal Handler:", newGoal);
  };

  return (
    <form className="new-goal" onSubmit={addGoalHandler}>
      <input type="text" />
      <button type="submit">Add Goal</button>
    </form>
  );
};

export default NewGoal;

7. Efficient Communication Between Child to Parent

  • In parent component build a callback function to handle data in current component
  • Pass the callback function pointer via a prop from the parent component to the child component
  • In child component call the callback function with parameters through which we pass data to parent component

Parent component:

// ./App.js
import React from "react";

// component start with an uppercase character
import GoalList from "./components/GoalList";
import NewGoal from "./components/NewGoal";

// styles are always applied globally
import "./App.css";

const App = () => {
  const courseGoals = [
    { id: "cg1", text: "Learn Javascript" },
    { id: "cg2", text: "Learn React" },
    { id: "cg3", text: "Learn Redux" },
    { id: "cg4", text: "Help others in course Q&A" },
  ];

  const addNewGoalHandler = (newGoal) => {
    courseGoals.push(newGoal);
    console.log(courseGoals);
  };

  return (
    <div className="course-goals">
      <h2>Course Goals</h2>
      <NewGoal onAddGoal={addNewGoalHandler} />
      <GoalList goals={courseGoals} />
    </div>
  );
};

export default App;

Child component:

// ./components/NewGoal.js
import React from "react";
import "./NewGoal.css";

const NewGoal = (props) => {
  const addGoalHandler = (event) => {
    event.preventDefault();
    const newGoal = {
      id: Math.random().toString(),
      text: "A new goal!",
    };
    props.onAddGoal(newGoal);
  };

  return (
    <form className="new-goal" onSubmit={addGoalHandler}>
      <input type="text" />
      <button type="submit">Add Goal</button>
    </form>
  );
};

export default NewGoal;

8. Working with "State"

  • Every react component have a state (snapshot)
  • We can use the useState hook to connect component state with the functional component itself
  • useState funciton need a param to get initial state and it return a array with two element, first element is state snapshot, the second element is state setting function
  • use the state setting function to change a component's state
  • When component's state is changed, the component will rerender to present new state in the UI

App component and it's state:

// ./App.js
import React, { useState } from "react";

// component start with an uppercase character
import GoalList from "./components/GoalList";
import NewGoal from "./components/NewGoal";

// styles are always applied globally
import "./App.css";

const App = () => {
  const [courseGoals, setCourseGoals] = useState([
    { id: "cg1", text: "Learn Javascript" },
    { id: "cg2", text: "Learn React" },
    { id: "cg3", text: "Learn Redux" },
    { id: "cg4", text: "Help others in course Q&A" },
  ]);

  const addNewGoalHandler = (newGoal) => {
    setCourseGoals((prevCourseGoals) => {
      return prevCourseGoals.concat(newGoal);
    });
  };

  return (
    <div className="course-goals">
      <h2>Course Goals</h2>
      <NewGoal onAddGoal={addNewGoalHandler} />
      <GoalList goals={courseGoals} />
    </div>
  );
};

export default App;

9. Fetching User Input (Two-way Binding)

  • Build a state for our custom component
  • Bind input's value with current state's snapshot
  • Bind input's onChange event with state setting function and pass input's value to the function
  • When input's content change, that will lead to state change and custom component's rerendering to present the changing

Component based on Two way Binding:

/ ./components/NewGoal.js
import React, { useState } from "react";
import "./NewGoal.css";

const NewGoal = (props) => {
  const [enteredText, setEnteredText] = useState("");

  const addGoalHandler = (event) => {
    event.preventDefault();
    const newGoal = {
      id: Math.random().toString(),
      text: enteredText,
    };

    props.onAddGoal(newGoal);
    setEnteredText("");
  };

  const textChangeHandler = (event) => {
    setEnteredText(event.target.value);
  };

  return (
    <form className="new-goal" onSubmit={addGoalHandler}>
      <input type="text" value={enteredText} 
      onChange={textChangeHandler} />
      <button type="submit">Add Goal</button>
    </form>
  );
};

export default NewGoal;

10. Source Code


Comments

Popular posts from this blog

WSL2配置proxychains, 使得终端走宿主机代理

Javascript Currying

Node.js & Express.js - A Refresher

What is MERN?