React从入门到扬弃,快捷通晓react

By admin in 4858美高梅 on 2019年4月15日

概况:

因此本篇小说你能够对react的主要有个整体的认识。
关于react是怎样,优点,消除哪些难点等,网上一大推就不啰嗦了。 

摸底虚拟DOM的兑现,参考那篇小说 

[虚拟DOM]
(https://www.zhihu.com/question/29504639)

简短讲,其实便是用一个轻量级的dom结构(用js模拟实现),来模拟重量级的dom结构,通过比对轻量级结构后,在操作重量级dom结构巩固品质,从而达到品质优化的指标。

概况:

通过本篇文章你能够对react的首要有个全体的认识。
至于react是何等,优点,消除什么难点等,网上一大推就不啰嗦了。
问询虚拟DOM的实现,参考那边文章
虚拟DOM
不想看的话归纳讲,其实就是用二个轻量级的dom结构(用js模拟实现),来效仿重量级的dom结构,通过比对轻量级结构后,在操作重量级dom结构巩固品质,从而达到品质优化的目标。

demo地址
https://github.com/leidenglai/react-ops

安装

npm i -S redux react-redux redux-devtools

生命周期:

高效学习react 先明白它的机要—-生命周期,
贰个组件在分歧时期会调用区别时期的函数接口约等于对应的生命周期函数

生命周期:

飞快学习react 先驾驭它的首要—-生命周期,
二个组件在不相同年代会调用区别时期的函数接口也正是应和的生命周期函数

React供给的入门知识

react其实作用很少,他只是一个顶住渲染页面包车型大巴框架,其利用的
Diff算法
使稳当前js在操作dom时消耗功用方面包车型客车难题获得有效的消除。
用脚本实行DOM操作的代价很昂贵。古板的做法中,js会大批量的操作dom,所以会消耗多量的效能,也是时刻。因为那几个原因react的虚拟dom的优势就显示出来了,它利用虚拟dom将实际的dom结构存储起来,每当状态发生变动时就会创设新的杜撰节点并与事先的虚构节点开始展览对照,然后渲染实际页面中变化的有的。整个经过并未有展开dom的获取和操作,将本来或然多次的dom操作,压缩到唯有2回渲染。
所以说react是一个ui框架。
因为react只负责ui渲染,要搞好三个类型,就必要任何工具和库的相配,如redux管理数据,单页应用react-router管理路由,
immutable
、 lodash
等帮忙插件。react已圆满协理ES6,ES6也万分须求,有ES六,那么她的好基友babel也不可缺少。还有正是前者以往风行的集调节和测试、压缩、构建于壹身的webpack,不会配备也要会用。
不是说好的功能少吗
那也正是干吗说react上手不方便了,可是像es六那种,不管你学不学react你都得调节。

概念

在redux中分为3个对象:Action、Reducer、Store

装载时代的函数

getDefaultProps(是设置暗中同意props)getInitialState(放弃,设置私下认可State)
依次执行以下函数 

• constructor

• componentWillMount 

• render 

• componentDidMount

装载时代的函数

getDefaultProps(是安装私下认可props)getInitialState(吐弃,设置默许State)
梯次实行以下函数
4858美高梅,• constructor
• componentWillMount
• render
• componentDidMount

React的组件

react的机件其实有点像二个舒适型的html标签,你能够自定义那个标签怎么显得,能干什么,之后在其他地点能重复引用。
react的组件是由props
、state数据和rander视图等结合。props是开端数据,不可变的,壹般来着父组件传递;
state决定了可变的和用户交互的数量,它的意况调整着视图的景况。与任何框架监听数据动态改换dom不一样,react选拔setState来调节视图的换代。setState会自动调用render函数,触发视图的再度渲染,若是仅仅只是state数据的转移而从未调用setState,并不会接触更新,所以必须运用setState()修改state。
组件就是富有独立作用的视图模块,大多小的零件组成3个大的零件,整个页面便是由二个个组件组合而成。它的益处是便于重复利用和维护。
一个轻便的组件写法(ES陆 class类创造组件,脸书官方推荐的写法):

import React from 'react';

export class TestComponents extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
      //...
    };
  }
  render() {
    return (<div>Hello World!</div>)
  }
}

Action

  1. 对行为(如用户作为)的虚幻
  2. React从入门到扬弃,快捷通晓react。Action 就是八个家常 JavaScript
    对象。如:{ type: 'ADD_TODO', text: 'Go to swimming pool' }(在这之中type字段是预定也是必须的)
  3. 作为Reducer的参数
履新时期的函数

若是组件的数量有调换了(porp,state), 依次推行以下函数 

• componentWillReceiveProps 

• shouldComponentUpdate

 • componentWillUpdate

 • render 

• componentDidUpdate

履新时期的函数

比方组件的数额有转移了(porp,state), 依次实施以下函数
• componentWillReceiveProps
• shouldComponentUpdate
• componentWillUpdate
• render
• componentDidUpdate

生命周期函数

实例化
第二次实例化
getDefaultProps
getInitialState
componentWillMount
render
componentDidMount

实例化实现后的更新
getInitialState
componentWillMount
render
componentDidMount
存在期
组件已存在时的动静改动

componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
销毁&清理期
componentWillUnmount

Reducer

  1. 1个数见不鲜的函数,用来修改store的情状。
  2. 函数具名:(currentState,action)=>newState
    1. 在 default 情状下回到currentState
    2. Object.assign({},state, { visibilityFilter: action.filter })(第叁个参数不可能为state)
      等价于ES七的 { ...state, ...newState }
  3. redux 的 combineReducers 方法可统1reducer
卸载时代的函数

销毁组件

•componentWillUnmount

1. import React,{ Component } from 'react';
2. class Demo extends Component {
3.  constructor(props) {
4.    // 构造函数,要创造一个组件类的实例,会调用对应的构造函数,
5.    //一个react组件需要构造函数,往往为了两个目的.
6.    //1:初始化state.2.绑定成员函数this环境。  
7.    // 无状态的函数就不需要构造函数,
8.      super(props)
9.      console.log("---初始化组件---")
10.      this.state = {
11.        test:'想要显示一段不一样的文字'
12.         //定义state,存放页面的数据,通过this.setState()方法修改
13.        //.this.setState()函数所做的事情,首先是改变this.state的值,然后驱动组件经历更新过程,这样才有机会让this.state里新的值出现在界面上。
14.      }
15.  }
16. componentWillMount () {
17.    console.log("---组件挂载前---最先执行的函数")
18. }
19. componentDidMount () {
20.    console.log("---组件挂载后---")
21. }
22. componentWillReceiveProps (nextProps) {
23.    console.log("---父组件重新渲染---")
24. 值得注意的是,更新时期的componentWillReceiveProps函数,
25. 只要父组件的render函数被调用,在render函数里面被渲染的子组件就会经历更新过程,不管父组件传给子组件的Props有没有改变,都会触发子组件的componentWillReceiveProps函数,但是自身的this.setState方法触发的更新过程不会调用这个函数。
26. }
27. shouldComponentUpdate (nextProps,nextState) {
28.    console.log("---组件接受到重绘状态---")
29.    它决定了一个组件什么时候不渲染。
30.    在更新过程中shouldComponemtUpdata 返回 false那就立刻停止更新。
31.    this.setState函数后会执行shouldComponemtUpdata 然后在决定我要不要更新。
32.  相反 shouldComponemtUpdata 函数返回 TRUE,接下来就会依次调用
33.   componentWillUpdata,render,componetDidUpdata函数,它把render像夹心面包似得夹在了中间。
34. }
35. componentWillUpdate (nextProps,nextState) {
36.  console.log("---组件将要更新---")
37. } 
38. componentDidUpdate (prevProps,prevState) {
39.   console.log("---组件更新完毕---")
40. }
41. render () {
42.    console.log("---组件渲染---")
43.    return (
44.        <div>{this.state.test}</div>
45.    )
46. }
47. componentWillUnmount () {
48.   console.log("---组件销毁---")
49. }
50. }
51. export default Demo;

 

component威尔Mount 和componentDidMount的分别:component威尔Mount
能够在服务器调用,也足以在浏览器调用可是componentDidMount只可以在浏览器被调用,因为装载是1个组件放到DOM树上的经过,那么真正的装载是不容许在服务器上产生的,服务器的渲染并不会爆发DOM树。所以大家能够选择那或多或少。在componentDidMount被调用时候,组件已经被装载到DOM树上了,可放心的去操作渲染出来的别的DOM。

卸载时代的函数

销毁组件
•componentWillUnmount

import React,{ Component } from 'react';

class Demo extends Component {
  constructor(props) {
    // 构造函数,要创造一个组件类的实例,会调用对应的构造函数,
    //一个react组件需要构造函数,往往为了两个目的.
    //1:初始化state.2.绑定成员函数this环境。  
    // 无状态的函数就不需要构造函数,
      super(props)
      console.log("---初始化组件---")
      this.state = {
        test:'想要显示一段不一样的文字'
         //定义state,存放页面的数据,通过this.setState()方法修改
        //.this.setState()函数所做的事情,首先是改变this.state的值,然后驱动组件经历更新过程,这样才有机会让this.state里新的值出现在界面上。
      }
  }
componentWillMount () {
    console.log("---组件挂载前---最先执行的函数")

}
componentDidMount () {
    console.log("---组件挂载后---")
}
componentWillReceiveProps (nextProps) {
    console.log("---父组件重新渲染---")
值得注意的是,更新时期的componentWillReceiveProps函数,
只要父组件的render函数被调用,在render函数里面被渲染的子组件就会经历更新过程,不管父组件传给子组件的Props有没有改变,都会触发子组件的componentWillReceiveProps函数,但是自身的this.setState方法触发的更新过程不会调用这个函数。
}
shouldComponentUpdate (nextProps,nextState) {
    console.log("---组件接受到重绘状态---")
    它决定了一个组件什么时候不渲染。
    在更新过程中shouldComponemtUpdata 返回 false那就立刻停止更新。
    this.setState函数后会执行shouldComponemtUpdata 然后在决定我要不要更新。
  相反 shouldComponemtUpdata 函数返回 TRUE,接下来就会依次调用
   componentWillUpdata,render,componetDidUpdata函数,它把render像夹心面包似得夹在了中间。
}
componentWillUpdate (nextProps,nextState) {
  console.log("---组件将要更新---")
} 
 componentDidUpdate (prevProps,prevState) {
   console.log("---组件更新完毕---")
}
render () {
    console.log("---组件渲染---")
    return (
        <div>{this.state.test}</div>
    )
}
componentWillUnmount () {
   console.log("---组件销毁---")
}
}
export default Demo;

component威尔Mount 和componentDidMount的区别:component威尔Mount
可以在服务器调用,也足以在浏览器调用不过componentDidMount只可以在浏览器被调用,因为装载是2个零件放到DOM树上的历程,那么真正的装载是不容许在服务器上做到的,服务器的渲染并不会时有发生DOM树。所以大家能够动用这点。在componentDidMount被调用时候,组件已经棉被服装载到DOM树上了,可放心的去操作渲染出来的其余DOM。

Redux

首先,redux并不是必须的,它的成效相当于在种种成效模块顶层组件之上又加了叁个零件,成效是开展逻辑运算、储存数据和落实组件越发是顶层组件的数据通讯。即使组件之间的交换不多,逻辑不复杂,只是独自的实行视图的渲染,没要求用redux,用了相反影响开采进程。不过假若组件交换越发频仍,逻辑很复杂的三个行使,那redux的优势就尤其分明了。

Store

  1. 意味着数据模型,内部维护了2个state变量
  2. 几个宗旨措施,分别是getState、dispatch。前者用来博取store的状态(state),后者用来修改store的意况
  3. createStore(reducer) 可创建Store

redux示例:

import { createStore } from 'redux'

// reducer
function counter(state = 0, action) {
    switch (action.type) {
        case 'INCREMENT':
            return state + 1
        default:
            return state
    }
}

// state
let store = createStore(counter); // 会调用

// 监听
store.subscribe(() =>
    console.log(store.getState())
);

// 调用reducer
store.dispatch({ type: 'INCREMENT' });

编纂组件:

组件间的传递通过props举行传递,看上面例子

 import React from 'react';

// 一级父组件

class Level1 extends React.Component{

   render(){

       return  <Level2 color='red'/>

   }

}

// 二级子组件

class Level2 extends React.Component{

   render(){

       return  <Level3 color={this.props.color}/>

   }

}

// 三级孙子组件

class Level3 extends React.Component{

   render(){

       return  <div color={{color: this.props.color}}/>

   }

}

 

也足以那样创造

  1. import React from ‘react’;

    const Level1 = React.createClass({  
    
     render() {
    
       return (
    
         <div></div>
    
       );
    
     }
    
    });
    
    export default Level1 ;  
    

     

编写组件:

组件间的传递通过props举行传递,看下边例子

import React from 'react';
// 一级父组件
class Level1 extends React.Component{
    render(){
        return  <Level2 color='red'/>
    }
}
// 二级子组件
class Level2 extends React.Component{
    render(){
        return  <Level3 color={this.props.color}/>
    }
}
// 三级孙子组件
class Level3 extends React.Component{
    render(){
        return  <div color={{color: this.props.color}}/>
    }
}

也能够这样创立

import React from 'react';
const Level1 = React.createClass({  
  render() {
    return (
      <div></div>
    );
  }
});
export default Level1 ;  

redux的基本原理实际上正是围绕着store进行

4858美高梅 1

redux的基本原理实际上正是环绕着store实行的。
react-redux是对redux流程的一种包装,使其能够适配与react的代码结构。
react-redux首先提供了三个Provider,能够将从createStore重回的store放入context中,使子集能够获取到store并开始展览操作;

<Provider store={store}>
    {() => <App />}
</Provider>

react-redux

react的需求:

  1. 数量连接单向从顶层向下分发的
  2. 组件之间的维系通过晋级state:子组件改变父组件state的章程只好是通过onClick触发父组件注解好的回调
  3. state越来越复杂:单页应用的上进导致。包蕴服务器响应、缓存数据、本地转移尚未持久化到服务器的多少,也席卷
    UI
    状态,如激活的路由,被入选的标签,是还是不是出示加载动作效果可能分页器等等。

react-redux 将react组件分为二种:显示组件 和 容器组件

React.createClass和extends Component的区别:

Component{}是ES陆的写法,会活动三番五次Component里面包车型客车特性createClass({})是React的ES伍写法,会变动三个React Component 语法差异 

• propType 和 getDefaultProps 

• 状态的不同 

• this区别 

• Mixins

 参考这篇文章 

[React.createClass和extends Component的区别]
(https://segmentfault.com/a/1190000005863630)

 若是你的组件是无状态的,纯输出组件也足以一贯写成函数如下

  1. function Pure(props){

      return(
    
          <div>{props.xxxx}</div>
    
      )
    
    }
    

     

react 组件必须顶尖超级传递
,借使想要越级传递,1直接到五,那么须求用到redux

4858美高梅 2 

redux

redux从前最棒刺探下flux,可是redux越来越美好。
react和redux事实上是三个单身的东西,如若你两者单独使用推荐react-redux库,大家从redux
使用办法开首,安分守己过渡到react-redux,那么些库能够让大家简化代码的书写

React.createClass和extends Component的区别:

Component{}是ES6的写法,会自行三番五次Component里面包车型地铁性质
createClass({})是React的ES5写法,会转换二个React Component
语法不一样
• propType 和 getDefaultProps
• 状态的区分
• this区别
• Mixins
参照那篇文章
React.createClass和extends
Component的区别
就算您的零件是无状态的,纯输出组件也得以直接写成函数如下

function Pure(props){
   return(
       <div>{props.xxxx}</div>
   )
}

react 组件必须一流拔尖传递

4858美高梅 3

clipboard.png

假定想要越级传递,1直接到伍,那么必要用到redux

redux和react怎么合作呢

react-redux提供了connect和Provider七个主意,它们三个将零件与redux关联起来,1个将store传给组件。组件通过dispatch发出action,store依照action的type属性调用对应的reducer并传到state和那些action,reducer对state进行拍卖并回到二个新的state放入store,connect监听到store爆发变化,调用setState更新组件,此时组件的props也就随之变动。
地点那1段解释有点绕,所以必然要看
文档
,将action、store、reducer三者的涉嫌理清

import React from 'react';
import { connect } from 'react-redux';

class TestComponents extends React.Component {
    //...
}

function mapStateToProps(state) {
  return {
        //redux要传递给当前组件props上的数据,如:
        data: state.data
    };
}

export default connect(mapStateToProps)(TestComponents)

那是二个组件模块与redux关联的大致例子,将redux上的多少data绑定到了TestComponents的props对象上。
connect(mapStateToProps, mapDispatchToProps, mergeToProps)(App);
率先个函数接收store中state和props,使页面能够依照近期的store中state和props再次来到新的stateProps;
第三个函数接收store中的dispatch和props,使页面能够复写dispatch方法,重返新的dispatchProps;
其八个函数接收前二个函数生成的stateProps和dispatchProps,在抬高原来的props,合并成新的props,并传给原始根节点的props。

4858美高梅 4

redux把数据流程规范化,统1保管多个store对象,当更新根数据,相关绑定数据都会活动进行翻新。
然则缺点是不客观的利用时,当3个零件相关数据更新时,纵然父组件不须要用到这么些组件,父组件依然会另行render,恐怕要求写shouldComponentUpdate()拓展决断优化,然则多少复杂时便于掉坑里。

展示组件

叙述如何展现:负责UI样式的显得

  1. 数据出自:props
  2. 数量修改:通过props的回调函数
  3. 不直接利用redux
在redux框架下,2个react组件是这么运维的

读取Store的境况,用于初始化组件的情景,同时监听Store的情景退换,当Store状态产生转移时候,就供给立异组件的动静,从而使得渲染。当必要更新store状态时,就要派发action对象。
依据当下props,和state,渲染用户分界面。

redux

redux以前最棒刺探下flux,不过redux越发赏心悦目。
react和redux事实上是七个单身的事物,倘若你两者单独行使推荐react-redux库,我们从redux
使用格局初始,安分守纪过渡到react-redux,那么些库能够让大家简化代码的书写

下1篇:React+Redux架构三个管理体系

容器组件

叙述怎么样运作:负责数据得到 和 状态更新

  1. 数据出自:redux state
  2. 多少修改:redux 派发action
  3. 直接行使redux

react-redux 只有2个API:Provider 和 connect

类别结构

actions—>用户作为 components—>组件 containers—>容器
reducer—>二个纯函数再次回到新的state状态 store–>
store里面负责分发action行为 index.html —> 模板文件 webpack—>
打包配置文件

在redux框架下,一个react组件是如此运营的

读取Store的情状,用于起始化组件的情况,同时监听Store的景况改造,当Store状态爆发转移时候,就须求更新组件的处境,从而使得渲染。当供给更新store状态时,将在派发action对象。
依照当前props,和state,渲染用户分界面。

Provider

<Provider store>

  1. 在原使用组件上包裹1层,使原先壹切应用成为Provider的子组件
  2. 接收Redux的store作为props,内部通过context对象传递给子孙组件上的connect
actions:

• 是1个表现的肤浅

 • 是普通JS对象 

• 一般由艺术生成

 • 必须有2个type 小编要增添一本书那个作为足以如下:

  1. const addTodo = (text) =>{

       retrun {
    
          type:'Add',
    
          id: nextTodoId++,
    
          text,
    
       }
    
    }
    

     

reducer: 

• 是响应的抽象 

• 是纯方法 

• 传入旧的景况和action 

• 再次来到新的情事

具名函数:reducer(state, action) state
是现阶段意况,action是经受到的action, 注意不能够改动参数state和action

  1. const todo = (state, action) =>{

       switch (action.type){
    
       case "Add_Book":
    
        return
    
         {
    
             text: action.text,
    
        }
    
    }
    

     

品类布局

actions—>用户作为
components—>组件
containers—>容器
reducer—>二个纯函数重临新的state状态
store–> store里面负责分发action行为
index.html —> 模板文件
webpack—> 打包配置文件

connect

connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])(Component)

作用:连接React组件与 Redux store

mapStateToProps(state, ownProps) : stateProps

  1. 将 store 中的数据作为 props 绑定到零部件上。
  2. 当 state 变化,大概 ownProps 变化的时候,mapStateToProps
    都会被调用,总括出二个新的 stateProps

mapDispatchToProps(dispatch, ownProps): dispatchProps:将
dispatch(action) 作为 props 绑定到零部件上

mergeProps:内定 stateProps 以及 dispatchProps 合并到 ownProps
的点子。(暗许使用Object.assign)

connect是个高阶组件(HOC)大概源码:

export default function connect(mapStateToProps, mapDispatchToProps, mergeProps, options = {}) {
  return function wrapWithConnect(WrappedComponent) {
    class Connect extends Component {
        constructor(props, context) {
            this.store = props.store || context.store
            this.stateProps = computeStateProps(this.store, props)
            this.dispatchProps = computeDispatchProps(this.store, props)
            this.state = { storeState: null }
            // 合并stateProps、dispatchProps、parentProps
            this.updateState()
        }
        shouldComponentUpdate(nextProps, nextState) {
            // 进行判断,当数据发生改变时,Component重新渲染
            if (propsChanged || mapStateProducedChange || dispatchPropsChanged) {
                this.updateState(nextProps)
                return true
            }
        }
        componentDidMount() {
            this.store.subscribe( () => this.setState({ storeState: this.store.getState() }) )
        }
        render() {
            return (
                <WrappedComponent {...this.nextState} />
            )
        }
      }
      return Connect;
    }
}

react-redux示例:

Counter.js

import React, { Component } from 'react';
import { createStore, bindActionCreators } from 'redux';
import { Provider, connect } from 'react-redux';

function clickReduce(state = { todo: 1 }, action) {
    switch (action.type) {
        case 'click':
            return Object.assign({}, state, { todo: state.todo + 1 });
        default:
            return state;
    }
}

let store = createStore(clickReduce);

class Counter extends Component {
    render() {
        return (
            <div>
                <div>{this.props.todo}</div>
                <button onClick={this.props.clickTodo}>Click</button>
            </div>
        )
    }
}

// 方式1:
export default connect(state => ({ todo: state.todo }),
    dispatch => ({ clickTodo: () => dispatch({ type: 'click' }) }))(Counter)

// 方式2:
export default connect(state => ({ todo: state.todo }),
    dispatch => bindActionCreators({ clickTodo: () => ({ type: 'click' }) }, dispatch))(Counter);

index.js

import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { render } from 'react-dom';
import Clock from './Clock'

render((
<Provider store={store}>
    <Counter />
</Provider>), root);

在redux中,大家不得不dispatch轻便的action对象。
相应的在react-redux中,大家不得不定义同步的reducer方法。
下节将介绍在react-redux怎么着定义异步方法。让其尤其适用于生产条件。

用四个事例串起来:

统一筹划二个享有加减效能的档次:

Actions.js:

export const increment = (counterCaption) => {

 return {

   type: increment,

   counterCaption: counterCaption

 };

};



export const decrement = (counterCaption) => {

 return {

   type: decrement,

   counterCaption,//es6写法等同于counterCaption: counterCaption

 };

};

Reducer.js:

export default (state, action) => {

 const {counterCaption} = action;//等同于const counterCaption= action.counterCaption;



 switch (action.type) {

   case increment:

     return {...state, [counterCaption]: state[counterCaption] + 1};

   case decrement:

     return {...state, [counterCaption]: state[counterCaption] - 1};



   default:

     return state

 }

}



//return {...state, [counterCaption]: state[counterCaption] - 1};等同于

//const newState = Object.assign({},state);

//newState[counterCaption]--;

//return newState;

 

Store.js:

import {createStore} from 'redux';

import reducer from './Reducer.js';



const initValues = {

 'First': 0,

 'Second': 10,

 'Third': 20

};



const store = createStore(reducer, initValues);



export default store;



//createStore是redux库提供的函数第一个参数是更新状态的reducer,第二参数是初始值

 

views(容器):

import React, { Component } from 'react';

import Counter from './Counter.js';



class ControlPanel extends Component {

 render() {

   return (

     <div>

       <Counter caption="First" />

       <Counter caption="Second" />

       <Counter caption="Third" />

     </div>

   );

 }

}

export default ControlPanel;

 

Counter.js(组件):

import React, { Component, PropTypes } from 'react';



import store from '../Store.js';

import * as Actions from '../Actions.js';



const buttonStyle = {

 margin: '10px'

};



class Counter extends Component {

 render() {

   const {caption, onIncrement, onDecrement, value} = this.props;



   return (

     <div>

       <button style={buttonStyle} onClick={onIncrement}>+</button>

       <button style={buttonStyle} onClick={onDecrement}>-</button>

       {caption} count: {value}

     </div>

   );

 }

}

//以下是对参数类型的定义,开启eslint需要写一下代码。

Counter.propTypes = {

 caption: PropTypes.string.isRequired,//表示caption是string类型,必填

 onIncrement: PropTypes.func.isRequired,

 onDecrement: PropTypes.func.isRequired,

 value: PropTypes.number.isRequired

};





class CounterContainer extends Component {

 constructor(props) {

   super(props);



   this.onIncrement = this.onIncrement.bind(this);

   this.onDecrement = this.onDecrement.bind(this);

   this.onChange = this.onChange.bind(this);

   this.getOwnState = this.getOwnState.bind(this);



   this.state = this.getOwnState();

 }



 getOwnState() {

   return {

     value: store.getState()[this.props.caption]

   };

 }



 onIncrement() {

   store.dispatch(Actions.increment(this.props.caption));

 }



 onDecrement() {

   store.dispatch(Actions.decrement(this.props.caption));

 }



 onChange() {

  //为了保持Store上的状态和this.state的同步

   this.setState(this.getOwnState());

 }



 shouldComponentUpdate(nextProps, nextState) {

   return (nextProps.caption !== this.props.caption) ||

     (nextState.value !== this.state.value);

 }



 componentDidMount() {

  //为了保持Store上的状态和this.state的同步

   store.subscribe(this.onChange);

 }



 componentWillUnmount() {

   //为了保持Store上的状态和this.state的同步

   store.unsubscribe(this.onChange);

 }



 render() {

//Counter 在上面

   return <Counter caption={this.props.caption}

     onIncrement={this.onIncrement}

     onDecrement={this.onDecrement}

     value={this.state.value} />

 }

}



CounterContainer.propTypes = {

 caption: PropTypes.string.isRequired

};



export default CounterContainer;

 

平凡大家会把容器放在container文件夹下,把组件放在component下 4858美高梅 54858美高梅 6

ControlPanel
根本就未有利用store,假使单单为了传递prop给组件counter将供给支持state
prop,鲜明不客观,在那之中react提供了Context的效益能够解决那几个主题素材;

actions:

• 是二个行事的空洞
• 是普通JS对象
• 一般由艺术生成
• 必须有三个type
自作者要增多1本书那么些行为足以如下:

const addTodo = (text) =>{
    retrun {
       type:'Add',
       id: nextTodoId++,
       text,
    }
}

reducer:
• 是响应的肤浅
• 是纯艺术
• 传入旧的情景和action
• 再次回到新的景观

签名函数:reducer(state, action) state
是当前情形,action是承受到的action,
瞩目无法更换参数state和action

const todo = (state, action) =>{
    switch (action.type){
    case "Add_Book": 
     return
      {
          text: action.text,
     }
}
Context:

大家扩展Provider.js,代码如下:

import {PropTypes, Component} from 'react';



class Provider extends Component {



 getChildContext() {

   return {

     store: this.props.store

   };

 }

 render() {

   return this.props.children; //Provider包裹的子元素输出出来

 }

}



Provider.contextTypes = {

 store: PropTypes.object

}

export default Provider;

 

index.js 文件引进Provider

import React from 'react';

import ReactDOM from 'react-dom';

import ControlPanel from './views/ControlPanel';

import store from './Store.js';

import Provider from './Provider.js';

ReactDOM.render(

 <Provider store={store}>

   <ControlPanel />

 </Provider>,

 document.getElementById('root')

);

 

最终大家在修改ControlPanel中的Counter组件, 4858美高梅 74858美高梅 84858美高梅 94858美高梅 10

用二个例证串起来:

设计多少个独具加减成效的种类:

Actions.js:

export const increment = (counterCaption) => {
  return {
    type: increment,
    counterCaption: counterCaption
  };
};

export const decrement = (counterCaption) => {
  return {
    type: decrement,
    counterCaption,//es6写法等同于counterCaption: counterCaption
  };
};

Reducer.js:

export default (state, action) => {
  const {counterCaption} = action;//等同于const counterCaption= action.counterCaption;

  switch (action.type) {
    case increment:
      return {...state, [counterCaption]: state[counterCaption] + 1};
    case decrement:
      return {...state, [counterCaption]: state[counterCaption] - 1};

    default:
      return state
  }
}

//return {...state, [counterCaption]: state[counterCaption] - 1};等同于
//const newState = Object.assign({},state);
//newState[counterCaption]--;
//return newState;

Store.js:

import {createStore} from 'redux';
import reducer from './Reducer.js';

const initValues = {
  'First': 0,
  'Second': 10,
  'Third': 20
};

const store = createStore(reducer, initValues);

export default store;

//createStore是redux库提供的函数第一个参数是更新状态的reducer,第二参数是初始值

views(容器):

import React, { Component } from 'react';
import Counter from './Counter.js';

class ControlPanel extends Component {
  render() {
    return (
      <div>
        <Counter caption="First" />
        <Counter caption="Second" />
        <Counter caption="Third" />
      </div>
    );
  }
}
export default ControlPanel;

Counter.js(组件):

import React, { Component, PropTypes } from 'react';

import store from '../Store.js';
import * as Actions from '../Actions.js';

const buttonStyle = {
  margin: '10px'
};

class Counter extends Component {
  render() {
    const {caption, onIncrement, onDecrement, value} = this.props;

    return (
      <div>
        <button style={buttonStyle} onClick={onIncrement}>+</button>
        <button style={buttonStyle} onClick={onDecrement}>-</button>
        {caption} count: {value}
      </div>
    );
  }
}
//以下是对参数类型的定义,开启eslint需要写一下代码。
Counter.propTypes = {
  caption: PropTypes.string.isRequired,//表示caption是string类型,必填
  onIncrement: PropTypes.func.isRequired,
  onDecrement: PropTypes.func.isRequired,
  value: PropTypes.number.isRequired
};


class CounterContainer extends Component {
  constructor(props) {
    super(props);

    this.onIncrement = this.onIncrement.bind(this);
    this.onDecrement = this.onDecrement.bind(this);
    this.onChange = this.onChange.bind(this);
    this.getOwnState = this.getOwnState.bind(this);

    this.state = this.getOwnState();
  }

  getOwnState() {
    return {
      value: store.getState()[this.props.caption]
    };
  }

  onIncrement() {
    store.dispatch(Actions.increment(this.props.caption));
  }

  onDecrement() {
    store.dispatch(Actions.decrement(this.props.caption));
  }

  onChange() {
   //为了保持Store上的状态和this.state的同步
    this.setState(this.getOwnState());
  }

  shouldComponentUpdate(nextProps, nextState) {
    return (nextProps.caption !== this.props.caption) ||
      (nextState.value !== this.state.value);
  }

  componentDidMount() {
   //为了保持Store上的状态和this.state的同步
    store.subscribe(this.onChange);
  }

  componentWillUnmount() {
    //为了保持Store上的状态和this.state的同步
    store.unsubscribe(this.onChange);
  }

  render() {
 //Counter 在上面
    return <Counter caption={this.props.caption} 
      onIncrement={this.onIncrement}
      onDecrement={this.onDecrement}
      value={this.state.value} />
  }
}

CounterContainer.propTypes = {
  caption: PropTypes.string.isRequired
};

export default CounterContainer;

常见我们会把容器放在container文件夹下,把组件放在component下

4858美高梅 11

clipboard.png

4858美高梅 12

clipboard.png

ControlPanel
根本就一贯不选拔store,如若唯有为了传递prop给组件counter将要求支持state
prop,显明不客观,个中react提供了Context的遵从能够化解这些难点;

React-Redux:

假诺知道地点的事例之后您会发现成个别复用的有的能够领到出来,各类零部件关注自个儿的片段就行了,react-redux库正是焚薮而田那几个事情的,让你付出爽到飞起

react-redux 规定,全数的 UI 组件都由用户提供,容器组件则是由
React-Redux
自动生成。约等于说,用户承担视觉层,状态管理则是任何交到它。

第3我们先领悟一下首要的函数connect,React-Redux 提供connect方法,用于从
UI 组件生成容器组件,就是将这二种组件连起来。 connect方法的欧洲经济共同体 API

import { connect } from 'react-redux'

const VisibleTodoList = connect(

 mapStateToProps,

 mapDispatchToProps

)(TodoList)

 

connect方法接受五个参数:mapStateToProps和mapDispatchToProps。它们定义了
UI 组件的事务逻辑。前者肩负输入逻辑,将要state映射到 UI
组件的参数(props),后者负责输出逻辑,就要用户对 UI 组件的操作映射成
Action。

这时index.js文件形成:

import React from 'react';

import ReactDOM from 'react-dom';

import {Provider} from 'react-redux';



import ControlPanel from './views/ControlPanel';

import store from './Store.js';

ReactDOM.render(

 <Provider store={store}>

   <ControlPanel/>

 </Provider>,

 document.getElementById('root')

);

//Provider在根组件外面包了一层,这样一来,App的所有子组件就默认都可以拿到state了

 

Counter.js文件形成

import React, { PropTypes } from 'react';

import * as Actions from '../Actions.js';

import {connect} from 'react-redux';



const buttonStyle = {

 margin: '10px'

};



function Counter({caption, onIncrement, onDecrement, value}) {

 return (

   <div>

     <button style={buttonStyle} onClick={onIncrement}>+</button>

     <button style={buttonStyle} onClick={onDecrement}>-</button>

     {caption} count: {value}

   </div>

 );

}



Counter.propTypes = {

 caption: PropTypes.string.isRequired,

 onIncrement: PropTypes.func.isRequired,

 onDecrement: PropTypes.func.isRequired,

 value: PropTypes.number.isRequired

};



function mapStateToProps(state, ownProps) {

 return {

   value: state[ownProps.caption]

 }

}



function mapDispatchToProps(dispatch, ownProps) {

 return {

   onIncrement: () => {

     dispatch(Actions.increment(ownProps.caption));

   },

   onDecrement: () => {

     dispatch(Actions.decrement(ownProps.caption));

   }

 }

}



export default connect(mapStateToProps, mapDispatchToProps)(Counter);

 

connect函数实际上是个高阶函数,理解能够参照这边文章 

[Higher-Order
Components]()

关于react 路由得以参照那边文章 

[路由]()

 

4858美高梅 13

 

Context:

大家增添Provider.js,代码如下:

import {PropTypes, Component} from 'react';

class Provider extends Component {

  getChildContext() {
    return {
      store: this.props.store
    };
  }
  render() {
    return this.props.children; //Provider包裹的子元素输出出来
  }
}

Provider.contextTypes = {
  store: PropTypes.object
}
export default Provider;

index.js 文件引进Provider

import React from 'react';
import ReactDOM from 'react-dom';
import ControlPanel from './views/ControlPanel';
import store from './Store.js';
import Provider from './Provider.js';
ReactDOM.render(
  <Provider store={store}>
    <ControlPanel />
  </Provider>,
  document.getElementById('root')
);

末尾大家在更改ControlPanel中的Counter组件,

4858美高梅 14

1.jpg

4858美高梅 15

2.jpg

4858美高梅 16

3.jpg

4858美高梅 17

4.jpg

React-Redux:

设若知道地点的例证之后您会意识有些复用的一部分能够领抽取来,各种零部件关怀自身的1些就行了,react-redux库正是缓解这几个事情的,让你付出爽到飞起

react-redux 规定,全数的 UI 组件都由用户提供,容器组件则是由
React-Redux
自动生成。也正是说,用户承担视觉层,状态管理则是全体提交它。

先是大家先通晓一下重点的函数connect,React-Redux 提供connect方法,用于从
UI 组件生成容器组件,便是将那二种组件连起来。
connect方法的总体 API

import { connect } from 'react-redux'
const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

connect方法接受多个参数:mapStateToProps和mapDispatchToProps。它们定义了
UI 组件的作业逻辑。前者肩负输入逻辑,将在state映射到 UI
组件的参数(props),后者负责输出逻辑,就要用户对 UI 组件的操作映射成
Action。

那会儿index.js文件产生:

import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';

import ControlPanel from './views/ControlPanel';
import store from './Store.js';
ReactDOM.render(
  <Provider store={store}>
    <ControlPanel/>
  </Provider>,
  document.getElementById('root')
);
//Provider在根组件外面包了一层,这样一来,App的所有子组件就默认都可以拿到state了

Counter.js文件造成

import React, { PropTypes } from 'react';
import * as Actions from '../Actions.js';
import {connect} from 'react-redux';

const buttonStyle = {
  margin: '10px'
};

function Counter({caption, onIncrement, onDecrement, value}) {
  return (
    <div>
      <button style={buttonStyle} onClick={onIncrement}>+</button>
      <button style={buttonStyle} onClick={onDecrement}>-</button>
      {caption} count: {value}
    </div>
  );
}

Counter.propTypes = {
  caption: PropTypes.string.isRequired,
  onIncrement: PropTypes.func.isRequired,
  onDecrement: PropTypes.func.isRequired,
  value: PropTypes.number.isRequired
};

function mapStateToProps(state, ownProps) {
  return {
    value: state[ownProps.caption]
  }
}

function mapDispatchToProps(dispatch, ownProps) {
  return {
    onIncrement: () => {
      dispatch(Actions.increment(ownProps.caption));
    },
    onDecrement: () => {
      dispatch(Actions.decrement(ownProps.caption));
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Counter);

connect函数实际上是个高阶函数,了然能够参见这边小说
Higher-Order
Components

至于react 路由得以参见这边小说
路由

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有