简介
React是用于构建用户界面的javascript库
- 特性
- 声明式编程
- 通过代码告诉计算机,你想的是什么,让计算机想出如何去做
- 命令式编程:告诉计算机去做什么
- 组件化
- 一次学会,随处编写
- 声明式编程
Main Concepts
Rendering Elements
To rendering an element into a root DOM node like <div id="root"></div>
, pass both to ReactDOM.render()
:
1 | const element = <h1>Hello, world</h1>; |
React elements are immutable. Once you create an element, you can’t change its children or attributes. React Only Updates What’s Necessary.
With our knowledge so far, the only way to update the UI is to create a new element, and pass it to ReactDOM.render()
.
Components and Props
Components are like JavaScript functions. They accept arbitrary inputs (called “props”) and return React elements.
1 | function Welcome(props) { |
This function is valid React component because it accept a single “props” object and return a React element.
You can also use an ES6 class
to define a component:
1 | class Welcome extends React.Component { |
Rendering a Component
React element not only can represent DOM tags, but also can represent user-defined components.
When React sees an element representing a user-defined component, it pass JSX attributes and children to this component as a single object. We call this obj “props”.
For example:
1 | function Welcome(props) { |
Props are Read-Only
React is pretty flexible but it has a single strict rule:
All React components must act like pure functions with respect to their props
State and Lifecycle
State is similar to props, but it it private and fully controlled by the component.
- Converting a Function to a Class
- Create an
ES6 class
, with the same name, that extendsReact.Component
- Create an
- Add a single empty method to it called
render()
- Add a single empty method to it called
- Move the body of the function into the
render()
method
- Move the body of the function into the
- Replace
props
withthis.props
in therender()
body
- Replace
- Delete the remaining empty function declaration
1 | class Clock extends React.Component { |
Adding Local State to a Class
- Add a
class constructor
that assigns the initialthis.state
- Class components should always call the base constructor with
props
1
2
3
4constructor(props) {
super(props);
this.state = {date: new Date()}
}
- Class components should always call the base constructor with
- Add a
- Replace
this.props.date
withthis.state.date
- Replace
Adding Lifecycle Methods to a Class
We can declare special methods on the component class to run some code when a component mounts and unmounts:
componentDidMount()
method runs after the component output has been rendered to the DOMcomponentWillUnmount()
- Use
this.setState()
to schedule updates to the component local state:- like:
this.setState({date: new Date()})
- like:
Using State Correctly
- Do Not Modify State Directly
- WRONG:
this.state.comment = "hello"
- CORRECT:
this.setState({comment: "hello"})
- the only place where you can assign
this.state
is the constructor
- WRONG:
- State Updates May Be Asynchronous
- React may batch multiple
setState()
calls into a single update for performance - Because of that, you should not rely on their values for calculating the next state
- To fix it, use a second form of
setState()
that accepts a function rather than an object- the function will receive the previous state as the first argument, and the props as the time update is applied as the second argument
this.setState((state, props)=>{})
- React may batch multiple
State Updates are Merged
The Date Flows Down
Both parent and children should not care if a certain component is stateful(class) or stateless(functionf). It is not accessible to any component other than the one that owns and sets it.
A component may choose to pass its state down as props to its child components: <FormattedDate date={this.state.date} />
This is commonly called a “top-down” or “unidirectional” data flow.
Handling Events
With JSX you pass a function as the handler, rather than string.
the Html:
1 | <button onclick="activateLasers()"> |
it is different in React
1 | <button onClick={activateLasers}> |
1 | function ActionLink() { |
Here, e
is a synthetic event. See the SyntheticEvent reference guide to learn more.
In JavaScript, class methods are not bound by defaul.
Generally, if you refer to a method without ()
after it, such as onClick={this.handleClick}
, you should bind that method. how funcions work in JavaScript.
Conditional Rendering
Use JavaScript operators like if
or conditonal operator
to Conditional Rendering.
Lists and Keys
Lists
You can use map()
to create listItems
in React:
1 | const numbers = [1, 2, 3, 4, 5]; |
When you render them, you’ll be given a warning that a key should be provided for list items.
Keys
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.
If you choose not to assign an explicit key to list items then React will default to using indexes as keys.
Extracting Components with Keys
Keys only make sense in the context of the surrounding array.
If you extract a ListItem components, you should keep the key on the <ListItem />
element, but not inside.
Forms
Controlled Components
An input form element whose value is controlled by React in this way is called a “controlled component”.
With a controlled component, the input’s value is always driven by the React state. For example:
1 | class NameForm extends React.Component { |
- set
value
attribute- the displayed value will always be
this.state.value
- the displayed value will always be
handleChange
- runs on every keystroke to update the React state, the displayed value will update as the user types
Composition vs Inheritance
Containment
Some component don’t know their children ahead of time. We recommend that such component use the special children
prop to pass children elements directly into their output.
1 | function E(props) { |
Anything inside the <E>
tag gets passed into the E
component as props.children
.
Some time you might need multiple “holes” in a componnet. You can:
1 | function E(props) { |