React(四)

前端组件化

一个简单的点赞功能


结构复用

实现简单的组件化

状态改变->构建新的DOM元素更新页面->重新插入新的DOM元素

搭建开发环境

// 安装create-react-app工具(一键生成所需要的工程目录,并做好各种配置和依赖)
// 工具地址:https://github.com/facebookincubator/create-react-app
npm install -g create-react-app

// 把npm的源改成taobao的源
npm config set registry https://registry.npm.taobao.org

// 通过create-react-app命令创建一个名为hello-react的工程
create-react-app hello-react

// 进入工程目录然后通过npm启动工程
cd hello-react
npm start

// http://localhost:3000/
// http://192.168.1.11:3000/

使用JSX描述UI信息

JSX原理

要点:
1.每个DOM元素的结构都可以用JS对象来表示。
2.编译的过程会把类似HTML的JSX结构转换成JS的对象结构。
3.JSX是JS语言的一种语法扩展。

组件的render方法

表达式插入

要点:
1.{}内可以放任何JS的代码。
2.表达式插入不但可以用在标签内部,也可以用在标签的属性上。
3.如果插入的表达式返回null,那么React会什么都不显示,相当于忽略了该表达式的插入。结合条件返回,可以做到显示或隐藏某些元素。

条件返回

{}内也可以放置JSX。

JSX元素变量(即JS对象)

可赋值给变量、作为函数参数传递、作为函数的返回值。

组件的组合、嵌套和组件树

事件监听

要点:
1.React封装了一系列的on*的属性(若没有经过处理,这些on*的事件监听只能用在普通的HTML的标签上,而不能用在组件标签上),地址:https://facebook.github.io/react/docs/events.html#supported-events。
2.事件属性名都必须要用驼峰命名法。

event对象

和普通浏览器一样,事件监听函数会被自动传入一个event对象(event对象并不是由浏览器所提供,而是由react内部所创建)。

关于事件中的this

要点:
1.React调用你所传给它的方法的时候,并不是通过对象方法的方式调用(this.handleClick),而是直接通过函数调用(handleClick),所以事件监听函数内并不能通过this获取到实例。
2.如果你想在事件函数当中使用当前的实例,你需要手动地将实例方法bind到当前实例上再传入给React的onClick事件监听,也可以在bind的时候给事件监听函数传入一些参数。

组件的state和setState

state

一个组件的显示形态是可以由它数据状态和配置参数决定的。

setState接收对象参数

要点:
1.setState方法由父类所提供。当我们调用这个函数的时候,React会更新组件的状态state,并且重新调用render方法,然后再把render方法所渲染的最新的内容显示到页面上。
2.接收一个对象或者函数作为参数。
3.传入一个对象的时候,这个对象表示该组件的新状态。但你只需要传入需要给更新的部分就可以了,而不需要传入整个对象。

setState接收函数参数

当你调用setState的时候,React并不会马上修改state。而是把这个对象放到一个更新队列里面,稍后才会从队列当中把新的状态提取出来合并到state当中,然后再触发组件更新。

setState合并

React内部会把JS事件循环中的消息队列的同一个消息中的setState都进行合并以后再重新渲染组件,因此不用担心多次进行setState会带来性能问题。

配置组件的props

要点:
1.每个组件都接收一个props参数,它是一个对象,包含了所有你对这个组件的配置。
2.组件内部通过this.props的方式获取到组件的参数。
3.在使用一个组件的时候,可以把参数放在标签的属性当中,所有的属性都会作为props对象的键值。
4.可以把任何类型的数据作为组件的参数,包括字符串、数字、对象、数组、甚至是函数等等。

默认配置defaultProps

里面是对props中各个属性的默认配置。

props不可变

props一旦传入,你就不可以在组件内部对它进行修改。但是你可以通过父组件主动重新渲染的方式来传入新的props,从而达到更新的效果。

state vs props

要点:
1.state的主要作用是用于组件保存、控制、修改自己的可变状态。(state是让组件控制自己的状态)
2.props的主要作用是让使用该组件的父组件可以传入参数来配置该组件。(props是让外部对组件自己进行配置)
3.尽量少用state,尽量多用props。
4.没有state的组件叫无状态组件,设置了state的叫做有状态组件。

渲染列表数据

渲染存放JSX元素的数组

使用map渲染列表数据

 

实战分析:评论功能(一)

组件划分

React中一切都是组件,用React构建的功能其实就是由各种组件组合而成。

组件实现

// 构建一个新的工程目录
create-react-app comment-app

// 在工程目录下的src/目录下新建四个文件
CommentApp.js
CommentInput.js
CommentList.js
Comment.js
// CommentApp.js
import React,{ Component } from 'react';
import CommentInput from './CommentInput';
import CommentList from './CommentList';

class CommentApp extends React.Component {
    render() {
        return (
            
) } } export default CommentApp
// CommentInput.js
import React,{ Component } from 'react';

class CommentInput extends React.Component {
    render() {
        return (
            
CommentInput
) } } export default CommentInput
// CommentList.js
import React,{ Component } from 'react';

class CommentList extends React.Component {
    render() {
        return (
            
CommentList
) } } export default CommentList
// 修改src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import CommentApp from './CommentApp';
import './index.css';

ReactDOM.render(
    ,
    document.getElementById('root')    
)
// 进入工程目录启动工程
npm run start

添加样式

// 修改CommentApp中的render方法,给它添加一个wrapper类名
import React,{ Component } from 'react';
import CommentInput from './CommentInput';
import CommentList from './CommentList';

class CommentApp extends React.Component {
    render() {
        return (
            
) } } export default CommentApp
// index.css
body {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
  background-color: #fbfbfb;
}
.wrapper {
  width: 500px;
  margin: 10px auto;
  font-size: 14px;
  background-color: #fff;
  border: 1px solid #f1f1f1;
  padding: 20px;
}

实战分析:评论功能(二)

处理用户输入

// 修改ComponentInput.js
import React,{ Component } from 'react';

class CommentInput extends React.Component {
    render() {
        return (
            
用户名:
评论内容: