Like any unfamiliar technology, React does have a learning curve. With practice and some patience, you will get the hang of it.
- React also streamlines how data is stored and handled, using state and props.
create react app
npm install -g create-react-app
npx create-react-app my-app
ornpm init react-app my-app
JSX: JavaScript + XML
Babel compiles JSX down to
React.createElement()
calls.
jsx
1 | const heading = <h1 className="site-heading">Hello, React</h1> |
non-jsx
1 | const heading = React.createElement('h1', { className: 'site-heading' }, 'Hello, React!') |
the feature of jsx:
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 />
Components
Whether you declare a component as a function or a class, it must never modify its own props.
Function
The simplest way to define a component is to write a JavaScript function:
1 | function Welcome(props) { |
Class Components
1 | import React, { Component } from 'react' |
Simple Components
The other type of component in React is the simple component, which is a function. This component doesn’t use the
class
keyword. Let’s take ourTable
and make two simple components for it - a table header, and a table body.
1 | const TableHeader = () => { |
1 | const TableBody = () => { |
1 | class Table extends Component { |
Everything should appear as it did before. As you can see, components can be nested in other components, and simple and class components can be mixed.
A class component must include render()
, and the return
can only return one parent element.
Converting a Function to a Class
convert a function component to a class in five steps:
- Create an ES6 class, with the same name, that extends
React.Component
. - Add a single empty method to it called
render()
. - Move the body of the function into the
render()
method. - Replace
props
withthis.props
in therender()
body. - Delete the remaining empty function declaration.
Props
Props are an effective way to pass existing data to a React component, however the component cannot change the props - they’re read-only.
- props are a way of passing data from parent to child.
State
State is similar to props, but it is private and fully controlled by the component.
State is reserved only for interactivity, that is, data that changes over time.
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.
You must use
this.setState()
to modify an array. Simply applying a new value tothis.state.property
will not work.ie.
1
2// Wrong
this.state.comment = 'Hello';1
2// Correct
this.setState({comment: 'Hello'});
tips:
Because this.props
and this.state
may be updated asynchronously, you should not rely on their values for calculating the next state.
ie.
1 | // Wrong |
use a second form of setState()
that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
1 | // Correct |
The Data Flows Down
If you imagine a component tree as a waterfall of props, each component’s state is like an additional water source that joins it at an arbitrary point but also flows down.
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.
This is commonly called a “top-down” or “unidirectional” data flow. Any state is always owned by some specific component, and any data or UI derived from that state can only affect components “below” them in the tree.
Lifecycle methods
constructor
componentDidMount
The
componentDidMount()
method runs after the component output has been rendered to the DOM.
componentWillUnmount
1 | class Clock extends React.Component { |
Let’s quickly recap what’s going on and the order in which the methods are called:
- When
<Clock />
is passed toReactDOM.render()
, React calls the constructor of theClock
component. SinceClock
needs to display the current time, it initializesthis.state
with an object including the current time. We will later update this state. - React then calls the
Clock
component’srender()
method. This is how React learns what should be displayed on the screen. React then updates the DOM to match theClock
’s render output. - When the
Clock
output is inserted in the DOM, React calls thecomponentDidMount()
lifecycle method. Inside it, theClock
component asks the browser to set up a timer to call the component’stick()
method once a second. - Every second the browser calls the
tick()
method. Inside it, theClock
component schedules a UI update by callingsetState()
with an object containing the current time. Thanks to thesetState()
call, React knows the state has changed, and calls therender()
method again to learn what should be on the screen. This time,this.state.date
in therender()
method will be different, and so the render output will include the updated time. React updates the DOM accordingly. - If the
Clock
component is ever removed from the DOM, React calls thecomponentWillUnmount()
lifecycle method so the timer is stopped.
总结:constructor->render()->componentDidMount()
state改变->render()
componentWillReceiveProps
componentWillReceiveProps在初始化render的时候不会执行,它会在Component接受到新的状态(Props)时被触发,一般用于父组件状态更新时子组件的重新渲染。
在componentWillReceiveProps中想作任何变更最好都将两个状态进行比较,假如状态有异才执行下一步。不然容易造成组件的多次渲染,并且这些渲染都是没有意义的。
Events
Conditional Rendering
Also remember that whenever conditions become too complex, it might be a good time to extract a component.
- Returning
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 Keys
Keep in mind that if the
map()
body is too nested, it might be a good time to extract a component.
Forms
Lifting State Up
Composition vs Inheritance
- Remember that components may accept arbitrary props, including primitive values, React elements, or functions.
Thinking 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.
- Remember: React is all about one-way data flow down the component hierarchy.