React基础大纲

React大纲

课程教学目标

  • React基本语法
  • React组件通信
  • State
  • Redux
  • React-Redux

React基础

脚手架

安装

npm isntall -g create-react-app

查看版本

create-react-app --version

创建项目

create-react-app my-app

进入项目目录

cd my-app

安装必要依赖

npm install

运行

npm start

开发者工具

React-developer-tools使用和安装

React的组件

官网地址:https://react.docschina.org

CDN方式引入
开发环境
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">
生产环境
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js">
在网页中使用React
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>Hello React!</title>
		<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
		<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
		<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
	</head>
	<body>

		<div id="example"></div>
		<script type="text/babel">
		const element =<h1>Hello, world!</h1>;
		ReactDOM.render(
    	element,
    	document.getElementById('example')
		);
		</script>

	</body>
</html>
JSX 语法

React 使用 JSX 来替代常规的 JavaScript。

JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。

我们不需要一定使用 JSX,但它有以下优点:

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
  • 它是类型安全的,在编译过程中就能发现错误。
  • 使用 JSX 编写模板更加简单快速。

元素是构成 React 应用的最小单位,JSX 就是用来声明 React 当中的元素。JSX 是在 JavaScript 内部实现的,与浏览器的 DOM 元素不同,React 当中的元素事实上是普通的对象,React DOM 可以确保 浏览器 DOM 的数据内容与 React 元素保持一致。

基础示例
const element = <h1 className="foo">Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
使用表达式
ReactDOM.render(
    <div>
      <h1>{1+1}</h1>
    </div>
    ,
    document.getElementById('example')
);
数组

JSX 允许在模板中插入数组,数组会自动展开所有成员:

var arr = [
  <h1>标题</h1>,
  <p>内容</p>,
];
ReactDOM.render(
  <div>{arr}</div>,
  document.getElementById('example')
);
创建组件
函数组件
function HelloMessage(props) {
    return <h1>Hello World!</h1>;
}
 
const element = <HelloMessage />;
 
ReactDOM.render(
    element,
    document.getElementById('example')
);
Class组件
class Welcome extends React.Component {
  render() {
    return <h1>Hello World!</h1>;
  }
}
函数组件和class组件的区别

无论是使用函数或是类来声明一个组件,它决不能修改它自己的 props

React是单项数据流,父组件改变了属性,那么子组件视图会更新。

属性 props 是外界传递过来的,状态 state 是组件本身的,状态可以在组件中任意修改,组件的属性和状态改变都会更新视图。

  • 使用class创建的组件,有自己的私有数据(this.state)和生命周期

  • 使用function创建的组件,只有props,没有自己的私有数据和生命周期函数。

  • 用构造函数创建的组件叫无状态组件,用class创建的组件叫有状态组件(受控组件和非受控组件)

使用范围

如果一个组件有自己的私有数据,则推荐使用class创建有状态组件;
如果一个组件不需要私有的数据,则推荐使用,无状态组件。

React组件的三大属性
state 属性

React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。状态通常被称为局部或封装。 除了拥有并设置它的组件外,其它组件不可访问。

React 里,只需更新组件的 state,然后根据新的state重新渲染用户界面(不要操作 DOM)。

state 是私有的,并且完全受控于当前组件,只有Class组件采用有state属性。

class Clock extends React.Component {
  //添加一个 class 构造函数,然后在该函数中为 this.state 赋初值
  constructor(props) {
    //Class 组件应该始终使用 props 参数来调用父类的构造函数。
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);
props属性

props 是不可变的,而 state 可以根据与用户交互来改变。\定义 state 来更新和修改数据。 组件只能通过 props 来传递数据和接受数据。

function HelloMessage(props) {
	return <h1>Hello {props.name}!</h1>;
}

const element = <HelloMessage name="Runoob"/>;

ReactDOM.render(
	element,
	document.getElementById('example')
);
state属性和props属性的区别
  • 组件中的props和state/data之间的区别

  • props的数据都是从外界传递过来的

  • state/data中的数据,都是组件私有的;(通过ajax获取的数据一般都是私有数据)

  • props中的数据都是只读的,不能重新赋值的。

  • state/data中的数据,都是可读可写的。

refs属性值

React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例

class MyComponent extends React.Component {
  handleClick() {
    // 使用原生的 DOM API 获取焦点
    this.refs.myInput.focus();
  }
  render() {
    //  当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs
    return (
      <div>
        <input type="text" ref="myInput" />
        <input
          type="button"
          value="点我输入框获取焦点"
          onClick={this.handleClick.bind(this)}
        />
      </div>
    );
  }
}
 
ReactDOM.render(
  <MyComponent />,
  document.getElementById('example')
);

React 进阶

React组件通信

React数据流动是单向的,

父传子

父组件通过props向子组件传递数据

子组件

import React from 'react';
import PropTypes from 'prop-types';

export default function Child({ name }) {
    return <h1>Hello, {name}</h1>;
}

Child.propTypes = {
    name: PropTypes.string.isRequired,
};

父组件

import React, { Component } from 'react';

import Child from './Child';

class Parent extends Component {
    render() {
        return (
            <div>
                <Child name="Sara" />
            </div>
        );
    }
}

export default Parent;
数据类型校验和默认值

默认值

组件使用props传递数据,同时可以设置props的默认值,如果父组件没有向子组件传递数据,可以使用默认值:

import React from 'react';
import PropTypes from 'prop-types';

export default function Child({ name }) {
    return <h1>Hello, {name}</h1>;
}

Child.propTypes = {
    name: PropTypes.string.isRequired,
};

Child.defaultProps={
    name:"world"
}

或者在有状态组件中,可以写成静态属性,但是必须使用像 transform-class-properties 的 Babel 转换工具,才可以在 React 组件类中声明 defaultProps 作为静态属性。此语法提案还没有最终确定,需要进行编译后才能在浏览器中运行。

import React from 'react';
import PropTypes from 'prop-types';

export default Class Child extends React.Component {
  static defaultProps={
    name:"world"
  }
  
  constructor(props){
    super(props);
    
  }
  
  render() {
    return (
      return <h1>Hello, {this.props.name}</h1>;
    );
  }
  
    return <h1>Hello, {name}</h1>;
}

数据类型校验

通过类型检查捕获大量错误。对于某些应用程序来说,你可以使用 FlowTypeScript 等 JavaScript 扩展来对整个应用程序做类型检查。但即使你不使用这些扩展,React 也内置了一些类型检查的功能。要在组件的 props 上进行类型检查,你只需配置特定的 propTypes 属性.

注意:

自 React v15.5 起,React.PropTypes 已移入另一个包中。请使用 prop-types 代替。

安装

npm install --save prop-types

使用

import PropTypes from 'prop-types';

class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}

Greeting.propTypes = {
  name: PropTypes.string
};

PropTypes 提供一系列验证器,可用于确保组件接收到的数据类型是有效的。出于性能方面的考虑,propTypes 仅在开发模式下进行检查。

import PropTypes from 'prop-types';

MyComponent.propTypes = {
  // 你可以将属性声明为 JS 原生类型,默认情况下
  // 这些属性都是可选的。
  optionalArray: PropTypes.array,
  optionalBool: PropTypes.bool,
  optionalFunc: PropTypes.func,
  optionalNumber: PropTypes.number,
  optionalObject: PropTypes.object,
  optionalString: PropTypes.string,
  optionalSymbol: PropTypes.symbol,

  // 任何可被渲染的元素(包括数字、字符串、元素或数组)
  // (或 Fragment) 也包含这些类型。
  optionalNode: PropTypes.node,

  // 一个 React 元素。
  optionalElement: PropTypes.element,

  // 一个 React 元素类型(即,MyComponent)。
  optionalElementType: PropTypes.elementType,

  // 你也可以声明 prop 为类的实例,这里使用
  // JS 的 instanceof 操作符。
  optionalMessage: PropTypes.instanceOf(Message),

  // 你可以让你的 prop 只能是特定的值,指定它为
  // 枚举类型。
  optionalEnum: PropTypes.oneOf(['News', 'Photos']),

  // 一个对象可以是几种类型中的任意一个类型
  optionalUnion: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(Message)
  ]),

  // 可以指定一个数组由某一类型的元素组成
  optionalArrayOf: PropTypes.arrayOf(PropTypes.number),

  // 可以指定一个对象由某一类型的值组成
  optionalObjectOf: PropTypes.objectOf(PropTypes.number),

  // 可以指定一个对象由特定的类型值组成
  optionalObjectWithShape: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number
  }),
  
  // An object with warnings on extra properties
  optionalObjectWithStrictShape: PropTypes.exact({
    name: PropTypes.string,
    quantity: PropTypes.number
  }),   

  // 你可以在任何 PropTypes 属性后面加上 `isRequired` ,确保
  // 这个 prop 没有被提供时,会打印警告信息。
  requiredFunc: PropTypes.func.isRequired,

  // 任意类型的数据
  requiredAny: PropTypes.any.isRequired,

  // 你可以指定一个自定义验证器。它在验证失败时应返回一个 Error 对象。
  // 请不要使用 `console.warn` 或抛出异常,因为这在 `onOfType` 中不会起作用。
  customProp: function(props, propName, componentName) {
    if (!/matchme/.test(props[propName])) {
      return new Error(
        'Invalid prop `' + propName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  },

  // 你也可以提供一个自定义的 `arrayOf` 或 `objectOf` 验证器。
  // 它应该在验证失败时返回一个 Error 对象。
  // 验证器将验证数组或对象中的每个值。验证器的前两个参数
  // 第一个是数组或对象本身
  // 第二个是他们当前的键。
  customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
    if (!/matchme/.test(propValue[key])) {
      return new Error(
        'Invalid prop `' + propFullName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  })
};

defaultProps 用于确保 this.props.name 在父组件没有指定其值时,有一个默认值。propTypes 类型检查发生在 defaultProps 赋值后,所以类型检查也适用于 defaultProps

子传父
  • 利用回调函数
  • 利用自定义事件机制

示例

实现在子组件中点击隐藏组件按钮可以将自身隐藏的功能

子组件

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class Child extends Component {
    static propTypes = {
        hideConponent: PropTypes.func.isRequired,
    }
    render() {
        return (
            <div>
                哈哈,我是Child
                <button onClick={this.props.hideConponent}>隐藏Child组件</button>
            </div>
        );
    }
}

export default List3;

父组件

import React, { Component } from 'react';

import Child from './components/Child';
export default class App extends Component {
    constructor(...args) {
        super(...args);
        this.state = {
            isShowList3: false,
        };
    }
    showConponent = () => {
        this.setState({
            isShowList3: true,
        });
    }
    hideConponent = () => {
        this.setState({
            isShowList3: false,
        });
    }
    render() {
        return (
            <div>
                <button onClick={this.showConponent}>显示Child组件</button>
                {
                    this.state.isShowList3 ?
                        <Child hideConponent={this.hideConponent} />
                    :
                    null
                }

            </div>
        );
    }
}
兄弟组件通信

也叫非嵌套组件通信。

利用二者共同父组件进行通信,但是采用组件间共同的父级来进行中转,会增加子组件和父组件之间的耦合度,如果组件层次较深的话,找到二者公共的父组件不是一件容易的事。

推荐使用自定义事件的方式。

安装events依赖

npm install events --save

新建event.js文件并向外提供一个事件对象,供通信时使用:

import { EventEmitter } from "events";
export default new EventEmitter();
跨组件通信(context)
State
setState()
内部状态
合并更新
异步更新
This指向
组件受控

###组件的生命周期

Todolist

组件拆分
实现添加列表、列表的显示
列表的编辑
过滤
清除所选

react-router-dom

介绍

安装

内置组件

4.2.1 BrowserRouter★★★★★

4.2.2 HashRouter★★★★★

4.2.3 Route★★★★★

4.2.4 Redirect★★★★★

4.2.5 Link★★★

4.2.6 Navlink★★★★★

4.2.7 Switch★★★

4.3 *嵌套路由*

4.3.1 嵌套路由的配置★★★★★

4.4 *路由传参*

4.4.1 参数传递★★★★★

5.1 *介绍*

5.1.1 介绍★★★

5.1.2 安装★★★

5.2 *R********edux的运行流程*

5.2.1 redux的运行流程★★★★★

5.3 *R********edux的核心概念*

5.3.1 Action★★★

5.3.2 Reducer★★★

5.3.3 Store★★★

5.4 *核心api*

5.4.1 createStore★★★

5.4.2 combinereducers★★★

5.4.3 applyMiddleware★★★

5.4.4 getState★★★

5.4.5 Subscribe★★★

5.4.6 Dispatch★★★

5.4.7 unsubscribe★★★

5.4.8 中间件redux-thunk★★★

6.1 *简介*

6.1.1 react-redux的概念★★★

6.1.2 安装及使用★★★

6.2 *R********eact-redux的概念*

6.2.1 react-redux的概念★★★

6.2.2 安装及使用★★★

6.3 *核心关键字*

6.3.1 Provider★★★

6.3.2 Connect★★★

6.4 *核心关键字*

6.4.1 mapStateToProps★★★

6.4.2 mapDispatchToProps★★★

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值