Learning React#
What is React#
React is a JavaScript library, used to build user interfaces (UI) on the front end.
React is not a framework (unlike Angular, which is more opinionated).
open-source project created by Facebook.
React is just some JavaScript helper libraries that we can load into our HTML.
React is the view layer of an MVC application (Model View Controller)
One of the most important aspects of React is the fact that you can create components, which are like custom, reusable HTML elements, to quickly and efficiently build user interfaces. React also streamlines how data is stored and handled, using state and props.
Create React app#
Create React App is an environment that comes pre-configured with everything you need to build a React app.
$ npx create-react-app react-tutorial $ cd react-tutorial && npm start
The
/src
directory will contain all React code.For
index.css
, if you want, you can use Bootstrap or whatever CSS framework you want, or nothing at all.We use
className
instead ofclass
. This is our first hint that the code being written here is JavaScript, and not actually HTML.<!-- This time, we are loading the Component as a property of React, so we no longer need to extend React.Component. --> import React, {Component} from 'react' import ReactDOM from 'react-dom' import './index.css' class App extends Component { render() { return ( <div className="App"> <h1>Hello, React!</h1> </div> ) } } ReactDOM.render(<App />, document.getElementById('root'))
Syntax for React functions
<!-- if not within a class need to include const --> const function_name = (paras) => { code }
React Developer Tools#
There is an extension called React Developer Tools that will make your life much easier when working with React. Download React DevTools for Chrome, or whatever browser you prefer to work on.
JSX: JavaScript + XML#
it is what looks like HTML in React code, but it’s not quite HTML. This is JSX, which stands for JavaScript XML.
With JSX, we can write what looks like HTML, and also we can create and use our own XML-like tags.
Using JSX is not mandatory for writing React. Under the hood, it’s running
createElement
, which takes the tag, object containing the properties, and children of the component and renders the same information.<!-- JSX --> const heading = <h1 className="site-heading">Hello, React</h1> <!-- No JSX --> const heading = React.createElement('h1', {className: 'site-heading'}, 'Hello, React!')
JSX is actually closer to JavaScript, not HTML, so there are a few key differences to note when writing it.
className
is used instead ofclass
for adding CSS classes, asclass
is a reserved keyword in JavaScript.Properties and methods in JSX are camelCase -
onclick
will becomeonClick
.Self-closing tags must end in a slash - e.g.
<img />
JavaScript expressions can also be embedded inside JSX using curly braces, including variables, functions, and properties.
const name = 'Tania' const heading = <h1>Hello, {name}</h1>
Elements#
TO ADD.
Components#
Almost everything in React consists of components, which can be class components or simple components.
component可以直接写在最终文档里或者也可以写成一个单独的文件,即可以导入到另一个文件的
.js
文件模组; 可以在各处重复使用。
React components can be declared either as JS functions or ES6 class
Coverting an function component to a class in five steps:
Create an ES6 class, with the same name, that extends
React.Component
Add a signle empty method to it called
render()
Move the body of the function into the
render()
methodReplace
props
withthis.props
in therender()
bodyDelete the remaining empty function declaration
class Clock extends React.Component { render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.props.date.toLocaleTimeString()}.</h2> </div> ); } }
A good rule of thumb is that if a part of your UI is used several times (Button, Panel, Avatar), or is complex enough on its own (App, FeedStory, Comment), it is a good candidate to be extracted to a separate component.
Class Components#
We create a custom class component as we wanted
We capitalize custom components to differentiate them from regular HTML elements.
Import the component in the e.g.
App.js
fileThen by loading it into the
render()
ofApp
, we load the componentclass ClassComponent extends Component { render() { return <div>Example</div> } } export default ClassComponent
Simple Components#
Simple component is a function. This component doesn’t use the
class
keyword.const SimpleComponent = () => { return <div>Example</div> }
Simple components can be used withwin class components
components can be nested in other components, and simple and class components can be mixed.
Note
A class component must include
render()
, and thereturn
can only return one parent element.
Props#
One of the big deals about React is how it handles data, and it does so with properties, referred to as props, and with state.
we can access all props through
this.props
You should always use keys when making lists in React, as they help identify each list item.
Props are an effective way to pass existing data to a React component, however the component cannot change the props - they’re read-only.
We (React offical doc) recommend naming props from the component’s own point of view rather than the context in which it is being used.
Props are Read-Only; All React components must act like pure functions with respect to their props.
const TableBody = (props) => { const rows = props.characterData.map((row, index) => { return ( <tr key={index}> <td>{row.name}</td> <td>{row.job}</td> </tr> ) }) return <tbody>{rows}</tbody> } class Table extends Component { render() { const {characterData} = this.props return ( <table> <TableHeader /> <TableBody characterData={characterData} /> </table> ) } } class App extends Component { render() { const characters = [ { name: 'Charlie', job: 'Janitor', }, { name: 'Mac', job: 'Bouncer', }, { name: 'Dee', job: 'Aspring actress', }, { name: 'Dennis', job: 'Bartender', } ] return ( <div className="container"> <Table /> </div> ) } }
State#
With props, we have a one way data flow, but with state we can update private data from a component.
You can think of state as any data that should be saved and modified without necessarily being added to a database - for example, adding and removing items from a shopping cart before confirming your purchase.
The object will contain properties for everything you want to store in the state.
class App extends Component { state = { characters: [ { name: 'Charlie', // the rest of the data }, ], } }
To retrieve the state, we’ll get
this.state.characters
using the same ES6 method as before. To update the state, we’ll usethis.setState()
, a built-in method for manipulating state. We’ll filter the array based on anindex
that we pass through, and return the new array.Note
You must use this.setState() to modify an array. Simply applying a new value to this.state.property will not work.
state can’t be modified directly, instead, use
setState()
; The only place where you can assignthis.state
is the constructor.when update state, don’t use
this.state
orthis.props
as input since they may be updated asynchronously (?)When calling
setState()
, React merges the object you provide into the current state.a state created with multiple variables that can be updated individually and independently with the final state merges the latest updates from all variables
Neither parent nor child components can know if a certain component is stateful or stateless, and they shouldn’t care whether it is defined as a function or a class.
This is why state is often called local or encapsulated. It is not accessible to any component other than the one that owns and sets it.
The value of the state in the parent component can be passed to the child component as props, but the child component wouldn’t know whether it is state or props from the parent; This is commonly called a “top-down” or “unidirectional” data flow.
Using React Router for a SPA (single page application)#
Routing is how a web applications direct traffic.
In Single Page Application (or SPA) - only one page is loaded, and every click to a new page loads some additional JSON data, but does not actually request a new resource like loading index.html and about-me.html would.
Two potential dependencies for using routing
$ npm install react-router-dom axios
Browser router#
To use
react-router-dom
, we need to wrap our entireApp
component inBrowserRouter
. There are two types of routers:BrowserRouter
- makes pretty URLs likeexample.com/about
.HashRouter
- makes URLs with the octothorpe (or hashtag, if you will) that would look likeexample.com/#about
.
Route and switch#
Switch
- Groups all your routes together, and ensures they take precedence from top-to-bottom.Route
- Each individual route.
Link#
In order to link to a page within the SPA, we’ll use
Link
. If we used the traditional<a href="/route">
, it would make a completely new request and reload the page, so we haveLink
to help us out.
Handling events#
Difference in handling events b/t React and HTML
Syntax difference
the way to prevent default behavior, i.e. in React, use
preventDefault()
Binding in JSX callbacks (?)
this.handleClick = this.handleClick.bind(this)
Conditional Rendering#
Use
if
statement to conditionally render a componentUse inline condtions in JSX
Inline
if
with logical&&
operator: It works because in JavaScript,true && expression
always evaluates toexpression
, andfalse && expression
always evaluates tofalse
.Inline If-Else with Conditional Operator
avaScript conditional operator
condition ? true : false
.
Use conditional rendering to prevent component from rendering
essentially return
null
when not wanting the component to be renderedReturning
null
from a component’srender
method does not affect the firing of the component’s lifecycle methods. For instancecomponentDidUpdate
will still be called.
Lists and kyes#
A “key” is a special string attribute you need to include when creating lists of elements.
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity
The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. Most often you would use IDs from your data as keys
const todoItems = todos.map((todo) => <li key={todo.id}> {todo.text} </li> );
When you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort:
const todoItems = todos.map((todo, index) => // Only do this if items have no stable IDs <li key={index}> {todo.text} </li> );
don’t indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state.
Keys only make sense in the context of the surrounding array (what is surrounding array?).
A good rule of thumb is that elements inside the
map()
call need keys.
Keys must only be unique among siblings; However, they don’t need to be globally unique.
Forms#
Controlled components#
the React component that renders a form also controls what happens in that form on subsequent user input. An input form element whose value is controlled by React in this way is called a “controlled component”.
It can sometimes be tedious to use controlled components, because you need to write an event handler for every way your data can change and pipe all of the input state through a React component.
In these situations, you might want to check out uncontrolled components, an alternative technique for implementing input forms.
Lifting state up#
In React, sharing state is accomplished by moving it up to the closest common ancestor of the components that need it. This is called “lifting state up”.
replace
this.state.xxx
withthis.props.xxx
in the descendant component.however, props are read-only, we can use
this.setState()
in the local/descendant components to update itIn React, this is usually solved by making a component “controlled”.
There should be a single “source of truth” for any data that changes in a React application. Usually, the state is first added to the component that needs it for rendering. Then, if other components also need it, you can lift it up to their closest common ancestor. Instead of trying to sync the state between different components, we should rely on the top-down data flow.
Composition vs inheritance#
React has a powerful composition model, and we recommend using composition instead of inheritance to reuse code between components.
Containment#
Some components don’t know their children ahead of time. Such components can use the special
children
prop to pass children elements directly into their output
Specialization#
Sometimes we think about components as being “special cases” of other components. In React, this is also achieved by composition, where a more “specific” component renders a more “generic” one and configures it with props
Thinking in React#
Step 1: Break The UI Into A Component Hierarchy#
But how do you know what should be its own component? Use the same techniques for deciding if you should create a new function or object.
One such technique is the single responsibility principle, that is, a component should ideally only do one thing. If it ends up growing, it should be decomposed into smaller subcomponents.
Step 2: Build A Static Version in React#
You can build top-down or bottom-up. That is, you can either start with building the components higher up in the hierarchy or with the ones lower in it.
In simpler examples, it’s usually easier to go top-down, and on larger projects, it’s easier to go bottom-up and write tests as you build.
Step 3: Identify The Minimal (but complete) Representation Of UI State#
To make your UI interactive, you need to be able to trigger changes to your underlying data model. React achieves this with state.
To figure out which one is state, ask three questions about each piece of data:
Is it passed in from a parent via props? If so, it probably isn’t state.
Does it remain unchanged over time? If so, it probably isn’t state.
Can you compute it based on any other state or props in your component? If so, it isn’t state.
Step 4: Identify Where Your State Should Live#
Remember: React is all about one-way data flow down the component hierarchy. It may not be immediately clear which component should own what state. This is often the most challenging part for newcomers to understand, so follow these steps to figure it out:
For each piece of state in your application:
Identify every component that renders something based on that state.
Find a common owner component (a single component above all the components that need the state in the hierarchy).
Either the common owner or another component higher up in the hierarchy should own the state.
If you can’t find a component where it makes sense to own the state, create a new component solely for holding the state and add it somewhere in the hierarchy above the common owner component.
Step 5: Add Inverse Data Flow#
Notes from personal website building using React Static#
static.config.js
controls the overall site structure and “meta data”It creates routes which is binded with specific pages and provides environmental data to those pages
It also control page/sub-page structure by specifying
children
in the routehaven’t figure out how to load multiple
.md
files here and attach them to certain route (!!)
Learned how to use CSS to control the UI of web pages; Html & CSS are tbe basics that need to learn more
Installing and using packages for additional needs
Use
react-pdf
to render PDF file on webpagemarkdown-yaml-metadata-parser
: to parse.md
files intometadata
andcontent
react-markdown
” to render.md
files in React. seems to be the most popular one with ability to add plugin to extend its functionalities
Basic file structure for the site
static.config.js
: see abovepackage.json
: dependencies (packages) are listed here./src
: source folder, contains most of the programs./src/pages
: contains.js
(other types, e.g..md
) files that are rendered into web pages./src/containers
: supporting.js
files, such as templates./src/assets
: attachments (files, pics, etc.) for webpages
App.js
: file that references web pages, puts them in one placeapp.css
: setting up the UI for web page components/elementsindex.js
: file to renderApp.js
Running questions#
what is ReactDOM
when need to use
const
when creating a new objectwhen to use class component vs simple component
when to use
this.xx
when set up/use a prop/state in a class (vs in a function) component
in functions, we use React Hooks to achieve the same purupose
what is an
event
what is a constructor?
what is mounting/unmounting? –> lifecycle methods?
What is W3C synthetic event? 10, what is webpack