react知识点回顾
来源于互联网
# 一、npm的配置
切换淘宝镜像源
npm config set registry https://registry.npm.taobao.org
npm config get registry
npm install -g cnpm --registry=https://registry.npm.taobao.org
使用npm安装react
cnpm install react react-dom --save
# 二、开发环境配置
这里使用
create-react-app初始化项目
npm install create-react-app -g
安装完成之后就可以在命令行使用
create-react-app了,首先选择一个合适的目录,然后只需要简单地输入
create-react-app yourfilename
# 三、认识JSX
# 3.1 JSX 简介
JSX其是一个语法扩展,它既不是单纯的字符串,也不是HTML,虽然长得和HTML很像甚至基本上看起来一样。但事实上它是React内部实现的一种,允许我们直接在JS里书写UI的方式
# 3.2 JSX 属性
JSX的标签同样可以拥有自己的属性
const title = <h1 id="main">React Learning</h1>
// 注意是 className 而不是 class
const title = <h1 className="main">React Learning</h1>
# 3.3 JSX 嵌套
JSX的标签也可以像HTML一样相互嵌套,一般有嵌套解构的JSX元素外面,我们习惯于为它加上一个小括号
const title = (
<div>
<h1 className="main">React Learning</h1>
<p>Let's learn JSX</p>
</div>
)
需要注意的是,
JSX在嵌套时,最外层有且只能有一个标签,否则就会出错
// 这是一个错误示例
const title = (
<h1 className="main">React Learning</h1>
<p>Let's learn JSX</p>
)
# 3.4 JSX表达式
在
JSX元素中,我们同样可以使用JavaScript表达式,在JSX当中的表达式需要用一个大括号括起来
function sayhi(name) {
return 'Hi,' + name
}
const title = (
<div>
<h1 className="main">React Learning</h1>
<p>Let's learn JSX. <span>{sayhi('you')}</span></p>
</div>
)
# 四、组件类型
# 4.1 函数定义与类定义组件
第一种函数定义组件,非常简单啦,我们只需要定义一个接收
props传值,返回React元素的方法即可
function Title(props) {
return <h1>Hello, {props.name}</h1>
}
// 甚至使用ES6的箭头函数简写之后可以变成这样
const Title = props => <h1>Hello, {props.name}</h1>
第二种是类定义组件,也就是使用
ES6中新引入的类的概念来定义React组件
- 组件在定义好之后,可以通过
JSX描述的方式被引用,组件之间也可以相互嵌套和组合
class Title extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>
}
}
# 4.2 展示与容器组件
// 展示组件
class CommentList extends React.Component {
constructor(props) {
super(props)
}
renderComment({body, author}) {
return <li>{body}—{author}</li>
}
render() {
return <ul> {this.props.comments.map(this.renderComment)} </ul>
}
}
// 容器组件
class CommentListContainer extends React.Component {
constructor() {
super()
this.state = { comments: [] }
}
componentDidMount() {
$.ajax({
url: "/my-comments.json",
dataType: 'json',
success: function(comments) {
this.setState({comments: comments})
}.bind(this)
})
}
render() {
return <CommentList comments={this.state.comments} />
}
}
展示组件
- 主要负责组件内容如何展示
- 从
props接收父组件传递来的数据 - 大多数情况可以通过函数定义组件声明
容器组件
- 主要关注组件数据如何交互
- 拥有自身的
state,从服务器获取数据,或与redux等其他数据处理模块协作 - 需要通过类定义组件声明,并包含生命周期函数和其他附加方法
那么这样写具体有什么好处呢?
- 解耦了界面和数据的逻辑
- 更好的可复用性,比如同一个回复列表展示组件可以套用不同数据源的容器组件
- 利于团队协作,一个人负责界面结构,一个人负责数据交互
# 4.3 有状态与无状态组件
有状态组件
这个组件能够获取储存改变应用或组件本身的状态数据,在
React当中也就是state,一些比较明显的特征是我们可以在这样的组件当中看到对this.state的初始化,或this.setState方法的调用
无状态组件
这样的组件一般只接收来自其他组件的数据。一般这样的组件中只能看到对
this.props的调用
// 有状态组件
class StatefulLink extends React.Component {
constructor(props) {
super(props)
this.state = {
active: false
}
}
handleClick() {
this.setState({
active: !this.state.active
})
}
render() {
return <a
style={{ color: this.state.active ? 'red' : 'black' }}
onClick={this.handleClick.bind(this)}
>
Stateful Link
</a>
}
}
// 无状态组件
class StatelessLink extends React.Component {
constructor(props) {
super(props)
}
handleClick() {
this.props.handleClick(this.props.router)
}
render() {
const active = this.props.activeRouter === this.props.router
return (
<li>
<a
style={{ color: active ? 'red' : 'black' }}
onClick={this.handleClick.bind(this)}
>
Stateless Link
</a>
</li>
)
}
}
在
React的实际开发当中,我们编写的组件大部分都是无状态组件。毕竟React的主要作用是编写用户界面。再加上ES6的新特性,绝大多数的无状态组件都可以通过箭头函数简写成类似下面这样
const SimpleButton = props => <button>{props.text}</button>
# 4.4 受控与非受控组件
受控组件
比如说设置了
value的<input>是一个受控组件。对于受控的<input>,渲染出来的html元素始终保持着value属性的值,如以下代码

- 此时如果想要更新用户的值。需要使用
onChange事件

非受控组件
即没有设置
value或者设置为null的是一个非受控组件,对于非受控的input组件,用户的输入会直接反映在页面上

- 上面的代码渲染出一个空值的输入框,用户的输入立即会反映在元素上
- 和受控组件一样,使用
onChange事件来监听值的变化,如果想要给组件设置一个非空的初始值。可以使用defaultValue属 - 通常情况下,
React当中所有的表单控件都需要是受控组件
# 4.5 组合与继承
React当中的组件是通过嵌套或组合的方式实现组件代码复用的- 通过
props传值和组合使用组件几乎可以满足所有场景下的需求。这样也更符合组件化的理念,就好像使用互相嵌套的DOM元素一样使用React的组件,并不需要引入继承的概念
继承的写法并不符合
React的理念。在React当中props其实是非常强大的,props几乎可以传入任何东西,变量、函数、甚至是组件本身
function SplitPane(props) {
return (
<div className="SplitPane">
<div className="SplitPane-left">
{props.left}
</div>
<div className="SplitPane-right">
{props.right}
</div>
</div>
)
}
function App() {
return (
<SplitPane
left={
<Contacts />
}
right={
<Chat />
} />
)
}
React官方也希望我们通过组合的方式来使用组件,如果你想实现一些非界面类型函数的复用,可以单独写在其他的模块当中在引入组件进行使用
# 五、组件数据
# 5.1 props
- 传入变量
- 传入函数
- 传入组件
props.children
- 在形式上,
props之于JSX就相当于attributes之于HTML。从写法上来看呢,我们为组件传入props就可以像为HTML标签添加属性一样- 在概念上,props对于组件就相当于JS中参数之于函数。我们可以抽象出这样一个函数来解释
props几乎可以传递所有的内容,包括变量、函数、甚至是组件本身
props是只读的
- 在
React中,props都是自上向下传递,从父组件传入子组件 - 并且
props是只读的,我们不能在组件中直接修改props的内容 - 也即是说组件只能根据传入的
props渲染界面,而不能在其内部对props进行修改
props类型检查
正是因为
props的强大,什么类型的内容都可以传递,所以在开发过程中,为了避免错误类型的内容传入,我们可以为props添加类型检查
props默认值
由于
props是只读的,我们不能直接为props赋值。React专门准备了一个方法定义props的默认值