react

框架库

  • react-router 路由
  • pubsub 音讯治理
  • redux 状态治理
  • ant-design UI库

要点

  • jsx 最初翻译过去就是React.createElement办法

    createElement(element,options,content)

    elment 元素名称

    options 属性对象

    content 属性外面的内容

    demo: createElement('h1',{id:'test'},'hello react')

  • 虚构dom解析后是Object
  • jsx注意事项

    1. 变量用一个大括号括起来;
    2. 如果援用class款式,须要用className
    3. 定义的jsx不须要引号,如果有多层,用小括号括起来
    4. 内联款式style要用对象的模式,且属性要用驼峰命名
    5. 只容许一个根标签
    6. 标签必须闭合
    7. 自定义组件以大写字母结尾

      const name='zhangsan'const Rdom=(    <div>        <h1 className='test' style={{fontSize:'20px'}}>{name}<h1>        <h1 className='test' style={{fontSize:'20px'}}>{name}<h1>    </div>)
  • react创立函数组件

    1. 函数名大写,且要有返回值
    2. 援用须要用标签,且标签要有闭合

      function Demo(){    return <h1>demo test</h1>}ReactDOM.render(<Demo/>,document.getElementById('test'))
  • react创立类组件

    1. 自定义组件类必须继承React.Component
    2. 类组件外面必须定义render办法,并且须要返回值
    3. 调用组件,渲染到页面,组件是命名是大写结尾
    4. 调用组件会new一个组件,而后调用render办法,且类外面this指向的是组件创立的实力对象,也叫组件实力对象。
    class MyComponent extends React.Component{       render(){           return (               <h1>test</h1>           )       }   }   ReactDOM.render(<MyComponent/>,document.getElementById('test'))
  • react事件以及state

    1.节点绑定事件须要用on+事件名,须要驼峰命名

    2.事件的回调函数须要用bind从新绑定,否则this会失落,或者用箭头函数赋值给属性,绑定该属性

    3.state对象外面须要定义须要变动的状态(属性)

    4.更改state外面的状态,须要用this.setState办法

    5.自定义办法须要用箭头函数赋值给属性,或者用bind办法绑定this

     class ChangeWeather extends React.Component{     constructor(){         super()         this.state={             flag:true         }         this.changeFlag=this.changeFlag.bind(this)     }     render(){         const {flag}=this.state         return (             <h1 onClick={this.changeFlag}>今天天气很{flag?'好':'不好'}</h1>         )     }     changeFlag(){        this.setState({            flag:!this.state.flag        })     } } ReactDOM.render(<ChangeWeather/>,document.getElementById('test'))
      //下面例子精简版class ChangeWeather extends React.Component {        state = { flag: true }        render() {            const { flag } = this.state            return (                <h1 onClick={this.changeFlag}>今天天气很{flag ? '好' : '不好'}</h1>            )        }        changeFlag = () => {            this.setState({                flag: !this.state.flag            })        }    }    ReactDOM.render(<ChangeWeather />, document.getElementById('test'))
  • react外面的props

    1.通过标签传递属性,能够通过扩大运算符进行传递

    2.组件外面通过props援用

    3.如果是变量须要用大括号的模式进行传递

     class ChangeWeather extends React.Component{       render (){           return (               <div>                    {this.props.title}                    {this.props.age}                    {this.props.obj.test}                    {this.props.test}                </div>           )       }   }    const obj={        test:123    }    ReactDOM.render(<ChangeWeather title="title" age={18} obj={obj} {...obj}/>, document.getElementById('test'))
  • props的属性限度以及默认值

    1.16.x版本之前是用React.propsType.xxxx进行限度,之后的版本是须要引入propstype.js,而后再类的propTypes属性下面进行定义

    2.限度属性的时候,间接定义到类下面进行限度

    3.如果是函数限度传的类型为func,而不是function

    4.如果没有传值,须要给默认值,须要再类的defaultProps属性下面进行定义默认值

    5.定义的这些规定须要咋渲染之前进行定义

    6.定义的属性规定也能够用动态属性进行定义static

     //间接定义到类下面class ChangeWeather extends React.Component{              render (){           return (               <div>                    {this.props.title}                    {this.props.age}                    {this.props.obj.test}                    {this.props.test}                </div>           )       }   }        //须要再渲染之前进行规定定义,在类的propTypes下面进行定义       ChangeWeather.propTypes = {            title: PropTypes.string.isRequired,            fun:PropTypes.func.isRequired//函数要用func这个类型        }        //默认值须要再类的defaultProps属性下面进行定义        ChangeWeather.defaultProps={            title:"fdsaf",            fun:function(){}                    }    const obj={        test:123,           }    ReactDOM.render(<ChangeWeather title="test" age={18} obj={obj} {...obj}/>,             document.getElementById('test'))
      //用动态属性的形式class ChangeWeather extends React.Component {        static propTypes = {            title: PropTypes.string.isRequired,            fun: PropTypes.func.isRequired        }        static defaultProps = {            title: "fdsaf",            fun: function () { }        }        render() {            return (                <div>                    {this.props.title}                    {this.props.age}                    {this.props.obj.test}                    {this.props.test}                </div>            )        }    }    const obj = {        test: 123,    }    ReactDOM.render(<ChangeWeather title="test" age={18} obj={obj} {...obj} />, document.getElementById('test'))
  • react外面的ref

    1.在节点外面通过ref属性进行绑定

    2.在逻辑外面通过refs承受

    3.承受的ref是一个实在节点

      class Test extends React.Component{        render(){            return (                <div>                    <input ref="input1" type="text"/>                    <button onClick={this.btnClick}>点击</button>                </div>            )        }        btnClick=() => {            const {input1}=this.refs            alert(input1.value)        }    }    ReactDOM.render(<Test/>,document.getElementById('test'))

    4.ref通过回调形式获取

     /* ref  回调函数的模式 */   class Reftest extends React.Component{       inputel=null       btnClick=() => {           alert(this.inputel.value)       }       render(){           return (               <div>                <input  type="text" ref={(el)=>{this.inputel=el}}/>                <button onClick={this.btnClick}>点击 </button>               </div>           )       }    }    ReactDOM.render(<Reftest/>,document.getElementById('test'))
    1. ref如果用内联的形式进行获取,在数据更新的 时候会调用两次回调函数,第一次会给回调函数传null第二次会传以后的节点。解决办法为间接用绑定的回调函数。只会调用一次回调函数,不会调用屡次。然而内联和绑定的形式不会有任何影响。开发中个别用内联的形式进行开发。
    2. ref的创立形式三,通过React.createRef的形式创立。该函数调用后会返回一个对象,keycurrent的对象,值为节点。有多少个ref就要调用几次后面的函数。官网举荐写法

       /* ref  React.createRef的形式 */   class Test extends React.Component{       //有多少个就要创立多少个       refstest=React.createRef();       btnclick=()=>{           console.log(this.refstest.current.value);                  }       render(){           return (               <div>                   //这里了是须要绑定下面返回的属性                    <input ref={this.refstest} type="text"/>                    <button onClick={this.btnclick}>点击</button>                </div>           )       }   }   ReactDOM.render(<Test/>,document.getElementById('test'))
  • react的非受控组件
  1. 所有的表单组件现用现取的组件。取值须要用到ref
  • react的受控组件

    1. 所有的输入框的值都存到状态外面,相似vue的双向绑定

          /* 受控组件*/    class Test extends React.Component {        state = {            name: ''        }        getTestValue = (e) => {            this.setState({                name: e.target.value            })        }        handleClick = () => {            console.log(this.state.name);        }        render() {            return (                <div>                    <input type="text" onChange={this.getTestValue} />                    <button onClick={this.handleClick}>点击</button>                </div>            )        }    }    ReactDOM.render(<Test />, document.getElementById('test'))
  • 函数的柯力化以及高阶函数

    1.高阶函数:

    1.1函数返回一个函数

    1.2 函数传参,该参数为一个函数

    2.柯力化函数:

    2.1函数返回函数,最初返回的函数一起解决后面函数的参数。

        class Test extends React.Component {        state = {            name: ''        }        getTestValue = (name) => {          return (event) => {            console.log(name,event);          }        }        handleClick = () => {            console.log(this.state.name);        }        render() {            return (                <div>                    <input type="text" onChange={this.getTestValue('test')} />                    <button onClick={this.handleClick}>点击</button>                </div>            )        }    }    ReactDOM.render(<Test />, document.getElementById('test'))
  • react的申明周期

    ReactDOM.unmountComponentAtNode(el)卸载组件

    //只有一获取值就销毁组件class Test extends React.Component {        getValue(key, e) {            ReactDOM.unmountComponentAtNode(document.getElementById('test'))        }        render() {            return (                <div>                    <input type="text" onChange={(e) => { this.getValue('userName', e) }} />                </div>            )        }    }    ReactDOM.render(<Test />, document.getElementById('test'))
  • react组件生命周期

    1.componentDidMount//组件挂在时调用,只调用一次

    2.componentWillUnmount //组件行将销毁

       /* 组件生命周期演示 */    class Test extends React.Component {        state = {            count: 1        }        timer = null;        render() {            const { count } = this.state;            return (                <div>                    <div> 数字:{count}</div>                    <div onClick={this.removeTimer}>点击我</div>                </div>            )        }        // 组件挂载        componentDidMount() {            this.timer = setInterval(() => {                let { count } = this.state;                count += 1;                this.setState({                    count,                })            }, 200)        }        // 组件行将卸载        componentWillUnmount() {            clearInterval(this.timer)        }        removeTimer = () => {            // 移除以后组件            ReactDOM.unmountComponentAtNode(document.getElementById('test'))        }    }    ReactDOM.render(<Test />, document.getElementById('test'))
  • 子组件生命周期执行程序

    1. constructor
    2. componentWillMount
    3. render
    4. componentDidMount
    5. componentWillUnmount
  • getSnapshotBeforeUpdate

       //初始化的申明周期执行程序class Demo extends React.Component {        constructor(props) {            super(props)            console.log('constructor');            this.state = {                count: 1            }        }        componentWillMount() {            console.log('componentWillMount');        }        componentWillUnmount() {            console.log('componentWillUnmount');        }        render() {            console.log('render');            const { count } = this.state            return (                <div>                    <div>展现的count:{count}</div>                    <div onClick={this.btnClick}>点击我</div>                    <div onClick={this.remove}>卸载组件</div>                </div>            )        }        remove = () => {            ReactDOM.unmountComponentAtNode(document.getElementById('test'))        }        btnClick = () => {            let { count } = this.state            count += 1;            this.setState({                count,            })        }    }    ReactDOM.render(<Demo />, document.getElementById('test'))
         class A extends React.Component{        state={            count:1        }        render(){            console.log('render');            const {count}=this.state            return (                <div>                    <B name={count}/>                    <div>count {count}</div>                    <div onClick={this.btnClick}>点击我</div>                </div>            )        }        // 跟新的时候会走这个生命周期,必须要返回true或者false,若返回false就不会执行前面的申明周期        shouldComponentUpdate(){            console.log('shouldComponentUpdate');            return true        }        componentWillUpdate(){             console.log('componentWillUpdate');        }        componentDidUpdate(){             console.log('componentDidUpdate');        }        btnClick=() => {            let {count}=this.state            count+=1;            this.setState({                count ,            })        }    }    class B extends React.Component{        //父组件传递的props更新了才会调用这个生命周期,首次不会调用该生命周期        componentWillReceiveProps(){            console.log('componentWillReceiveProps');        }        render(){            return (                <div>{this.props.name}</div>            )        }    }    ReactDOM.render(<A />, document.getElementById('test'))
      class Demo extends React.Component {        state = {            arr: []        }        componentDidMount() {            setInterval(() => {                const { arr } = this.state;                this.setState({                    arr: ['新闻' + (arr.length + 1), ...arr]                })            }, 1000)        }        // 新的申明周期,在更新前执行,能够像componentDidUpdate申明周期外面传递一个参数        getSnapshotBeforeUpdate() {            return this.refs.list.scrollHeight        }        componentDidUpdate(prepops, prestates, scrollheight) {            console.log(this.refs.list.scrollHeight, '...', scrollheight);            this.refs.list.scrollTop += this.refs.list.scrollHeight - scrollheight        }        render() {            return (                <div>                    <div className="list" ref="list">                        {                            this.state.arr.map((item, index) => {                                return (                                    <div key={index} className="li">{item}</div>                                )                            })                        }                    </div>                </div>            )        }    }    ReactDOM.render(<Demo />, document.getElementById('test'))
  • react diff算法

    1. 通过数据渲染成虚构dom
    2. 通过key值去判断是否存在雷同的值,如果key值雷同,判断对应的内容是否雷同,若内容雷同复用原来的dom,如果不雷同,创立新的dom渲染到页面,如果key值不雷同间接生成dom渲染到页面
    3. 应用index作为key值存在的问题:可能会使效率低下(旧dom可能复用不了),页面错位(若数据存在逆反操作)。
  • react脚手架

    1.全局装置npm i -g create-react-app

    2.进入要创立我的项目的目录控制台执行create-react-app projectName即创立胜利

  • 款式模块化

    1.利用文件名XXX.module.css,引入形式import hello from './xxx.module.css'在用的中央用hello.className的模式进行

    2.利用less进行嵌套

  • react组件父子通信

    1.父传子利用props进行传递

    2.子传父利用props给子组件传递函数,子组件通过props接管该函数,而后调用,且能够传值。

  • 公共用的状态放到父组件中(状态晋升),状态定义到哪里,对应的办法就对应在哪个组件中
  • 解决跨域

    1. 利用package.jsonproxy字段进行代理。申请的时候用本地的域名加端口号加接口名进行申请

      //pageage.json   "development": [      "last 1 chrome version",      "last 1 firefox version",      "last 1 safari version"    ],    "proxy":"http://localhost:5000"
       //申请的地址,端口号为本地的3000,3000代理到服务器为端口号5000的服务器axios.get('http://localhost:3000/students')      .then((res) => {        console.log(res.data)      })  }

      2.在我的项目目录src/下新建setupProxy.js文件,而后写入如下代码:

      const proxy = require('http - proxy - middleware');module.exports = function (app) {    app.use(proxy('/api', {         target: 'http://localhost:5000',        secure: false,        changeOrigin: true,        pathRewrite: {        "^/api": ""    },    }));};
  • 兄弟组件之间的通信,利用pubsubjs

    1. 装置pubsub-js

      yarn add pubsub-js

    2. 引入pubsubjs并在传递数据的组件中进行音讯公布,在须要获取数据的组件中进行音讯订阅

        componentDidMount() {        this.id=Pubsub.subscribe('getData', (name, stateObj) => {            this.setState(stateObj)         })    }componentWillUnmount(){    pubsub.undescribe(this.id)}request=()=>{        axios.get(            'http://localhost:3000/xxx'        )            .then((res) => {                Pubsub.publish('getData',{                    loading: false,                    users: res.data.items,                    err:false                })            })            .catch((err) => {                Pubsub.publish('getData',{                    loading: false,                    err:err.message                })             })}
  • react路由

    1.装置react-router-dom

    yarn add react-router-dom

    引入必要组件

    import React, { Component } from 'react'import { Link, Route } from 'react-router-dom'import About from './components/About'import Home from './components/Home'export default class App extends Component {  render() {    return (      <div>        <div className="row">          <div className="col-xs-offset-2 col-xs-8">            <div className="page-header"><h2>React Router Demo</h2></div>          </div>        </div>        <div className="row">          <div className="col-xs-2 col-xs-offset-2">            <div className="list-group">              {/* <a className="list-group-item active" href="./about.html">About</a>              <a className="list-group-item" href="./home.html">Home</a> */}              <Link to="/about" className="list-group-item">About</Link>              <Link to="/home" className="list-group-item">Home</Link>            </div>          </div>          <div className="col-xs-6">            <div className="panel">              <div className="panel-body">                {/* <h3>我是About的内容</h3> */}                <Route path='/about' component={About}/>              <Route path='/Home' component={ Home}/>            </div>          </div>        </div>        </div>        </div>    )  }}
    import React from 'react';import ReactDOM from 'react-dom';import { BrowserRouter } from 'react-router-dom'import './index.css';import App from './App';ReactDOM.render(  <BrowserRouter>    <App />  </BrowserRouter>,  document.getElementById('root'));
  • 通过this.props.children能够获取标签体内容
  • switch组件包裹路由只会匹配第一个匹配到 的路由进行渲染对应组件
  • react多级路由导致款式失落问题

    1. public文件下的index.html文件引入文件门路批改为/绝对路径的这种模式,或者用%PUBLIC_URL%这种模式进行引入。
    2. 或者将BrowserRouter组件换成HashRouter组件
  • `Router组件中的exact`属性用于精准匹配路由

     <Route exact path='/home' component={Home} />
  • Redirect组件用于没有匹配到门路的时候,调转到默认路由,个别放到注册组件最初
  • Switch组件用于匹配到第一个路由就不往后面进行匹配
  • NavLink用于路由高亮显示,能够自定义className
  • Link用于路由跳转

      <Switch>      <Route  path='/about/about' component={About} />      <Route exact path='/home' component={Home} />      <Redirect to="/home"></Redirect>   </Switch>
  • 嵌套路由

    1.子组件注册组件须要带上父组件的path

    • 父组件
    import React, { Component } from 'react'import { Switch, Route ,Redirect} from 'react-router-dom'import About from './pages/About'import Home from './pages/Home'import MyNavLink from './components/MyNavLink'import './App.css'export default class App extends Component {  render() {    return (      <div>        <div className="row">          <div className="col-xs-offset-2 col-xs-8">            <div className="page-header"><h2>React Router Demo</h2></div>          </div>        </div>        <div className="row">          <div className="col-xs-2 col-xs-offset-2">            <div className="list-group">              <MyNavLink to="/about" >About</MyNavLink>              <MyNavLink to="/home" >Home</MyNavLink>            </div>          </div>          <div className="col-xs-6">            <div className="panel">              <div className="panel-body">                <Switch>                  <Route  path='/about' component={About} />                  <Route  path='/home' component={Home} />                  <Redirect to="/home"></Redirect>                </Switch>              </div>            </div>          </div>        </div>      </div>    )  }}
    • 子组件
    import React from "react";import Message from "./Message";import News from "./News";import MyNavLink from "../../components/MyNavLink";import { Switch, Route,Redirect } from 'react-router-dom'export default class Home extends React.Component {    render() {        console.log(this.props);        return (            <div>                <h2>Home组件内容</h2>                <div>                    <ul className="nav nav-tabs">                        <li>                            <MyNavLink to="/home/news">News</MyNavLink>                                                    </li>                        <li>                            <MyNavLink to="/home/message">message</MyNavLink>                        </li>                    </ul>                    <Switch>                        <Route path="/home/news" component={News}></Route>                        <Route path="/home/message" component={Message}></Route>                        <Redirect to="/home/message"></Redirect>                    </Switch>                </div>            </div>        )    }}
  • 路由组件传参

    • params传参

      1.跳转的中央须要进行参数按程序传递

      2.注册的中央须要进行按程序进行接管

      3.子组件通过this.props.match.params获取

      import React, { Component } from 'react'import { Route } from 'react-router';import { Link } from 'react-router-dom';import MsgDetail from './MsgDetail';export default class Message extends Component {    state = {        students: [{            id: 1,            name: '张三',            age: 12        }, {            id: 2,            name: '李四',            age: 13        }, {            id: 3,            name: '王二',            age: 14        }]    }    render() {        const { students } = this.state;        return (            <div>                <ul>                    {                        students.map((item) => {                            return (                                <li>                                    <Link to={`/home/message/msgdetail/${item.name}/${item.age}`} key={item.id}>{item.name}</Link>                                </li>                            )                        })                    }                </ul>                <hr />                <Route path='/home/message/msgdetail/:name/:age' component={MsgDetail}/>                            </div>        )    }}

      4.子组件进行获取

      import React, { Component } from 'react';class MsgDetail extends Component {    render() {        console.log(this.props);        const { name, age } = this.props.match.params;        return (            <div>                {name}----{ age}            </div>        );    }}export default MsgDetail;
    • search传参(相似vue外面的query

      1.在跳转的中央进行传递

      2.在子组件的this.props.location.search进行取值

      3.须要将search参数进行转换成对象的模式

      import React, { Component } from 'react'import { Route } from 'react-router';import { Link } from 'react-router-dom';import MsgDetail from './MsgDetail';export default class Message extends Component {    state = {        students: [{            id: 1,            name: '张三',            age: 12        }, {            id: 2,            name: '李四',            age: 13        }, {            id: 3,            name: '王二',            age: 14        }]    }    render() {        const { students } = this.state;        return (            <div>                <ul>                    {                        students.map((item) => {                            return (                                <li>                                    <Link to={`/home/message/msgdetai?name=${item.name}&age=${age}`} key={item.id}>{item.name}</Link>                                </li>                             )                        })                    }                </ul>                <hr />                <Route path='/home/message/msgdetail' component={MsgDetail} />            </div>        )    }}

      4.子组件进行获取

      import React, { Component } from 'react';import qs from 'querystring'class MsgDetail extends Component {    render() {        console.log(this.props);        const { search } = this.props.location.search        const { name,age}=qs.parse(search.slice(1))        return (            <div>                {name}----{ age}            </div>        );    }}export default MsgDetail;
    • state传参

      1.路由跳转的中央须要通过对象的形式进行传递,须要蕴含path以及state属性。state属性是一个对象

      2.子组件通过this.props.locaiton.state进行获取

      3.state传递的参数在地址栏下面是看不到的,下面的两种都是在地址栏下面看的到的。

      import React, { Component } from 'react'import { Route } from 'react-router';import { Link } from 'react-router-dom';import MsgDetail from './MsgDetail';export default class Message extends Component {    state = {        students: [{            id: '00122',            name: '张三',            age: 12        }, {            id: '00233',            name: '李四',            age: 13        }, {            id: '003432423',            name: '王二',            age: 14        }]    }    render() {        const { students } = this.state;        return (            <div>                <ul>                    {                        students.map((item) => {                            return (                                <li key={item.id}>                                    <Link  to={{ path: '/home/message/msgdetail', state: { name: item.name, age: item.age } }}>{item.name}</Link>                                </li>                            )                        })                    }                </ul>                <hr />                <Route path='/home/message/msgdetail' component={MsgDetail} />            </div>        )    }}

      4.子组件进行接管

      import React, { Component } from 'react';import qs from 'querystring'class MsgDetail extends Component {    render() {        console.log(this.props);                const { name,age}=this.props.location.state        return (            <div>                {name}----{ age}            </div>        );    }}export default MsgDetail;
  • 编程式组件导航

    通过this.props.historyapi进行跳转

     jump = (name,age) => {        this.props.history.push('/home/message/msgdetail', { name, age } )    }
  • withRouter 若想在个别组件中应用路由跳转的api能够引入withRouter办法

    import React, { Component } from 'react'import { withRouter } from 'react-router-dom'class Header extends Component {    goBack = () => {         this.props.history.goBack()    }    goFowrd = () => {         this.props.history.goForward()    }    render() {        return (            <div className="page-header">                <h2>React Router Demo</h2>                <button onClick={this.goBack}>回退</button>                <button onClick={this.goFowrd}>后退</button>            </div>        )    }}export default withRouter(Header)
  • antd按需引入,可参考地址https://3x.ant.design/docs/react/use-with-create-react-app-cn中的高级配置
  • redux

    1.装置redux

    yarn add redux

    2.创立redux文件夹,在该文件下创立store文件,action文件,reducer文件,constent文件

3.store.js

import { createStore } from "redux";import countRedux from './count_redux'export default createStore(countRedux)

4.count_action.js

import {ADD,DESC } from './constent'export const add = (data) => ({    type: ADD,    data})export const desc = (data) => ({    type: DESC,    data})

5.count_redux.js

import { ADD,DESC} from './constent'export default function (preState=0, action) {    const { type,data}=action    switch (type) {        case ADD:            return preState + data        case DESC:            return preState - data        default:           return preState    } }

6.constent.js

export const ADD='add'export const DESC='desc'

7.index.js

import React from "react";import ReactDOM from "react-dom";import App from "./App.js";import store from './redux/store'ReactDOM.render(<App></App>, document.getElementById('root'))store.subscribe(() => {    ReactDOM.render(<App></App>, document.getElementById('root'))})
  • 异步action

    1.引入并装置redux-thunk

    2.利用中间件传入thunk

    3.action返回的是一个函数,该函数会带有dispatch函数参数

    代码如下:

    store.js

    import { createStore, applyMiddleware  } from "redux";import countRedux from './count_redux'import thunk from 'redux-thunk'export default createStore(countRedux, applyMiddleware(thunk))

    action.js

    export const  addAsync = (data, time) => {    //返回一个带有dispatch的参数的函数    return (dispatch) => {        setTimeout(() => {            dispatch(add(data))//调用同步action        },time)    }}
  • react-redux

    1.引入并装置

    yarn add react-redux

2.创立容器组件,用于操作状态以及包裹ui组件(链接ui组件以及redux)

      // 引入要展现的UI组件import countUi from '../../components/Count'// 用于连贯UI组件以及reduximport { connect } from 'react-redux'// 引入actionimport { add, desc, addAsync } from '../../redux/count_action'// 将store外面的状态映射到props,能够用过UI组件进行操作(ui组件通过this.props.xxx获取)function mapStateToProps(state) {     return {        count: state    }}// 将store外面的操作状态的办法映射到props,能够用过UI组件进行操作(ui组件通过this.props.xxx获取)function mapDispatchToProps(dispatch) {    return {        add: (num) => {            dispatch(add(num))        },        desc: (num) => {              dispatch(desc(num))        },        addasync: (num, time) => {            dispatch(addAsync(num,time))        }    }}export default connect(mapStateToProps, mapDispatchToProps)(countUi)     
  1. 通过props传递给子组件store
  2. UI组件的优化写法

    // 引入要展现的UI组件import countUi from '../../components/Count'// 用于连贯UI组件以及reduximport { connect } from 'react-redux'// 引入actionimport { add, desc, addAsync } from '../../redux/count_action'// 将store外面的状态映射到props,能够用过UI组件进行操作(ui组件通过this.props.xxx获取)/* function mapStateToProps(state) { return {    count: state}} */// 将store外面的操作状态的办法映射到props,能够用过UI组件进行操作(ui组件通过this.props.xxx获取)/* function mapDispatchToProps(dispatch) {return {    add: (num) => {        dispatch(add(num))    },    desc: (num) => {        dispatch(desc(num))    },    addasync: (num, time) => {        dispatch(addAsync(num,time))    }}} */// export default connect(mapStateToProps, mapDispatchToProps)(countUi)// 优化写法export default connect(state => ({ count: state }),//这里能够返回一个简略对象,外部能够主动散发action{    add: add,    desc: desc,    addasync: addAsync})(countUi)

    5.引入react-redux能够不必手动监听转态变动

    import React from "react";import ReactDOM from "react-dom";import App from "./App.js";// import store from './redux/store'ReactDOM.render(<App></App>, document.getElementById('root'))// 引入react-redux后能够不必手动监听状态变动// // 监测redux转态扭转,redux状态扭转会从新渲染页面// store.subscribe(() => {//     ReactDOM.render(<App></App>, document.getElementById('root'))// })

    6.利用react-reduxprovider传递store

    import React from "react";import ReactDOM from "react-dom";import App from "./App.js";import store from './redux/store'import { Provider } from 'react-redux'ReactDOM.render(<Provider store={store}>    <App /></Provider >, document.getElementById('root'))
  • 多个reducer利用combineReducers函数合并

    import { createStore, applyMiddleware ,combineReducers } from "redux";import countRedux from './reducers/count_redux'import person from "./reducers/person";import thunk from 'redux-thunk'export default createStore(  // 多个reducer用combineReducers合并  combineReducers({    count: countRedux,    person: person,  }),  applyMiddleware(thunk));
  • reducer必须是一个纯函数,即传入的什么参数,就返回改参数,且传入的参数不能被改写。如果传入的是对象或者是数组。返回的值也应该是一个对象或数组,不能够在原有的对象或数组中进行操作再返回

    import { ADD_PERSON } from "../constent";export default function (prestate=[],action) {     const { type, data } = action;    switch (type) {      case ADD_PERSON:        return [data,...prestate]      default:       return []    }}
  • redux配置的开发者工具

    1. 谷歌浏览器装置redux-devtools
    2. 在我的项目中装置redux-devtools-extension
    3. store.js中进行如下配置

      import { createStore, applyMiddleware  } from "redux";import thunk from 'redux-thunk'import { composeWithDevTools } from "redux-devtools-extension";import reducers from "./reducers";export default createStore(  // 多个reducer用combineReducers合并  reducers,  composeWithDevTools(applyMiddleware(thunk)));
  • 打包后的文件如何在本地启动

    1.全局装置serve插件

    npm install -g serve

    进入打包的文件目录运行serve命令