前言:React专注View层,一切皆组件;全部使用ES6语法,最新版本为React16。

Redux是专注于状态管理的库,和react解耦;单一状态,单向数据流。【独立团github地址


一、React基础知识

    React基础语法

  • import React
  • class语法新建组件,render里直接使用
  • render函数返回值就是输出JSX语法,会把JSX转成js执行

    React的View层语法

  • JS里直接写html
  • Class里要写成className
  • 变量用{ }包裹即可

    React的Api

  • 一切都是组件
  • 类实现组件,使用JSX语法
  • 组件间通信通过属性props传递
  1. 使用<组件 数据='值' >的形式传递
  2. 组件里使用this.props获取值
  3. 如果组件只有render函数,还可以用函数的形式写组件
  • 组件内部通过state管理状态
  1. JSX本质就是js,所以直接数组.map渲染列表,【注意列表项必需有唯一key】
  2. Constructor构造函数设置组件初始状态,记得执行super(props)
  3. State就是一个不可变的对象,使用this.state获取
  4. 通过this.setState修改,不能直接修改
  • onClick点击事件
  1. JSX里,onClick={this.函数名}来绑定事件
  2. this引用的问题,需要在构造函数里用bind绑定this,或者箭头函数直接绑定
  3. this.setState修改state,记得返回新的state,而不是修改

    React生命周期

  • 初始化周期
  • 组件重新渲染生命周期
  • 组件卸载声明周期

独立团Demo

  1. import React from 'react';
  2.  
  3. class App extends React.Component{
  4. render(){
  5. let boss = '李云龙'
  6. return (
  7. <div>
  8. <h2>独立团,团长{boss}</h2>
  9. <FirstYin leader='张大喵'></FirstYin>
  10. <Squadron leader='孙德盛'></Squadron>
  11. </div>
  12. )
  13. }
  14. }
  15.  
  16. function Squadron(props){
  17. return <h2>骑兵连连长{props.leader},冲啊!</h2>
  18. }
  19.  
  20. class FirstYin extends React.Component{
  21. constructor(props) {
  22. super(props)
  23. this.state = {
  24. solders: ['虎子', '柱子', '王根生']
  25. }
  26. // this.addSolder = this.addSolder.bind(this)
  27. }
  28. componentWillMount(){
  29. console.log('组件马上就要加载了')
  30. }
  31. componentDidMount(){
  32. console.log('组件加载完成了')
  33. }
  34. addSolder = () => {
  35. console.log('hello add solder')
  36. this.setState({
  37. solders: [...this.state.solders, '新兵蛋子编号:'+Math.random()]
  38. })
  39. }
  40. render(){
  41. console.log('组件正在加载')
  42. return (
  43. <div>
  44. <h2>一营营长,{this.props.leader}</h2>
  45. <button onClick={this.addSolder}>新兵入伍</button>
  46. <ul>
  47. {this.state.solders.map(solder => {
  48. return <li key={solder}>{solder}</li>
  49. })}
  50. </ul>
  51. </div>
  52. )
  53. }
  54. }
  55.  
  56. export default App;  

二、Redux基础知识

Redux核心概念

  • Store:保存数据的容器,一个应用只能有一个Store。Redux提供createStore函数,创建Store

    1. import {createStore} from 'redux';
    2. const store = createStore(fun); //createStore的参数为reducer函数  
  • State:数据状态。Store在某一时刻的状态,可以通过store.getState()获取到。

    1. const state = store.getState();
  • Action:Redux改变state必需通过Action,实际上是一个JSON对象,该对象必须包含type属性,表示Action的名称。

    1. //该函数不需要主动去调用,事实上我们在store.dispatch的时候,会自动触发。
    2. const action = {
    3. type: 'ADD', //action名称
    4. val: 5 //携带数据
    5. };    
  1. Action Creator:Action生成函数,用于创建Action,类似于工厂模式。若不使用,需要写很多Action。

    1. function createAdd(number) {
    2. return {
    3. type: 'ADD',
    4. val: number
    5. }
    6. }
    7. const action = createAdd(5);
  2. store.dispatch(action):View用于触发数据变化的唯一方式

    1. import {createStore} from 'redux';
    2. const store = createStore(fun);
    3.  
    4. store.dispatch({ //state+5
    5. type: 'ADD',
    6. val: 5
    7. }); 
  • Reducer:Action改变数据状态需要遵守的规律函数。

    1. const defaultState = 0;
    2.  
    3. //这里的reducer不需要主动去调用,我们只需要向容器中丢一块砖头(store.dispatch(action)),它会自动触发该方法
    4. const reducer = (state = defaultState, action) => {
    5. switch (action.type) {
    6. case 'ADD':
    7. return state + action.val;
    8. case 'DEC':
    9. return state - action.val;
    10. default:
    11. return state;
    12. }
    13. };

    注意:Reducer是一个纯函数,纯函数的要求之一是不能改写参数

    1. // 参数state和action是固定的
    2. function reducer(state, action) {
    3. let newSate = {};
    4. return { ...state, ...newSate}
    5. }
  • store.subscribe(listener):监听函数;会返回一个解除函数,调用该解除函数,就不再监听了
    1. import { createStore } from 'redux';
    2. const store = createStore(reducer);
    3.  
    4. let unsubscribe = store.subscribe(listener); //监听
    5.  
    6. unsubscribe(); //解除监听
  • 官方Demo

    1. import { createStore } from 'redux';
    2.  
    3. /**
    4. * 这是一个 reducer,形式为 (state, action) => state 的纯函数。
    5. * 描述了 action 如何把 state 转变成下一个 state。
    6. *
    7. * state 的形式取决于你,可以是基本类型、数组、对象、
    8. * 甚至是 Immutable.js 生成的数据结构。惟一的要点是
    9. * 当 state 变化时需要返回全新的对象,而不是修改传入的参数。
    10. *
    11. * 下面例子使用 `switch` 语句和字符串来做判断,但你可以写帮助类(helper)
    12. * 根据不同的约定(如方法映射)来判断,只要适用你的项目即可。
    13. */
    14. function reducer(state = 0, action) {
    15. switch (action.type) {
    16. case 'ADD':
    17. return state + action.val;
    18. case 'DES':
    19. return state - action.val;
    20. default:
    21. return state;
    22. }
    23. }
    24.  
    25. // 创建 Redux store 来存放应用的状态。
    26. // API 是 { subscribe, dispatch, getState }。
    27. let store = createStore(reducer);
    28.  
    29. // 可以手动订阅更新,也可以事件绑定到视图层。
    30. store.subscribe(() =>
    31. console.log("听到状态变化了:" + store.getState())
    32. );
    33.  
    34. // 改变内部 state 惟一方法是 dispatch 一个 action。
    35. // action 可以被序列化,用日记记录和储存下来,后期还可以以回放的方式执行
    36. store.dispatch({ type: 'ADD', val: 10 });
    37. // 10
    38. store.dispatch({ type: 'ADD', val: 20 });
    39. // 30
    40. store.dispatch({ type: 'DES', val: 30 });
    41. // 0  

    Redux单独使用

  • src->index.js中:所有状态归redux管理(组件只负责view显示)
  1. reducer新建store,随时通过store.getState获取状态

    1. import {createStore} from 'redux'
    2.  
    3. //通过reducer
    4. //根据老的 state和 action 生成新的state
    5. function counter(state=0, action){
    6. switch(action.type){
    7. case 'Add_GUN':
    8. return state+1
    9. case 'REMOVE_GUN':
    10. return state-1
    11. default:
    12. return 10
    13. }
    14. }
    15. //1、新建store
    16. const store = createStore(counter)
    17.  
    18. const init = store.getState()
    19. console.log(init) //10
  2. 需求状态变更,store.dispatch(action)来修改状态
    1. //2、派发事件 传递action
    2. store.dispatch({type: 'Add_GUN'})
    3. store.dispatch({type: 'REMOVE_GUN'})  
  3. reducer函数接收state和action,返回新的state,可以用store.subscribe监听每次修改
    1. //定义事件方法
    2. function listener(){
    3. const current = store.getState();
    4. console.log(`现在有机枪${current}把`)
    5. }
    6. //3、监听事件
    7. store.subscribe(listener)
  • 安装redux

    1. yarn add redux --sav
  • 启动项目
    1. yarn start

Redux和React一起用(手动连接)

      

  • Redux相关内容,移到单独的文件index.redux.js单独管理:reducer+action

    1. //action type
    2. const Add_GUN = '加机关枪'
    3. const REMOVE_GUN = '减机关枪'
    4.  
    5. //reducer
    6. export function counter(state=0, action){
    7. switch(action.type){
    8. case Add_GUN:
    9. return state+1
    10. case REMOVE_GUN:
    11. return state-1
    12. default:
    13. return 10
    14. }
    15. }
    16.  
    17. //action creator
    18. export function addGUN(){
    19. return {type: Add_GUN}
    20. }
    21. export function removeGUN(){
    22. return {type: REMOVE_GUN}
    23. }
  • App.js中:把store.dispatch方法传递给组件,内部可以调用修改状态
    1. import React from 'react';
    2.  
    3. class App extends React.Component{
    4. render(){
    5. const store = this.props.store
    6. const num = store.getState()
    7. const addGUN = this.props.addGUN
    8. const removeGUN = this.props.removeGUN
    9. return (
    10. <div>
    11. <h3>现在有机枪{num}把</h3>
    12. </div>
    13. )
    14. }
    15. }
    16.  
    17. export default App;
  • index.js中:Subscribe订阅render函数,每次修改都重新渲染
    1. import React from 'react';
    2. import ReactDOM from 'react-dom';
    3. import App from './App';
    4. import {createStore} from 'redux'
    5. import {counter, addGUN, removeGUN} from './index.redux'
    6.  
    7. const store = createStore(counter)
    8.  
    9. function render(){
    10. ReactDOM.render(<App store={store} addGUN={addGUN} removeGUN={removeGUN}/>, document.getElementById('root'));
    11. }
    12. render()
    13.  
    14. store.subscribe(render)

Redux处理异步

      

  • Redux默认只处理同步,异步任务需要react-thunk中间件
  1. 安装插件

    1. npm install redux-thunk --save  
  2. index.js中:使用applyMiddleware开启thunk中间件
    1. import {createStore, applyMiddleware} from 'redux'
    2. import thunk from 'redux-thunk'
    3. import {addGunAsync} from './index.redux'
    4.  
    5. const store = createStore(counter, applyMiddleware(thunk)) 
  3. index.redux.js中:Action可以返回函数,使用dispatch提交action
    1. //(模拟)异步函数提交dispatch
    2. export function addGunAsync(){
    3. return dispatch => {
    4. setTimeout(() => {
    5. dispatch(addGUN())
    6. }, 2000)
    7. }
    8. }
  4. App.js中:把store.dispatch方法传递给组件,内部可以调用修改状态

    1. import React from 'react';
    2.  
    3. class App extends React.Component{
    4. render(){
    5. const store = this.props.store
    6. const num = store.getState()
    7. const addGunAsync = this.props.addGunAsync
    8. return (
    9. <div>
    10. <h3>现在有机枪{num}把</h3>
    11. <button onClick={() => store.dispatch(addGunAsync())}>拖两天再给</button>
    12. </div>
    13. )
    14. }
    15. }

    Redux调试工具

      

  • 火狐搜索redux安装
  • 项目本地安装

    1. npm install redux-devtools-extension --save  
  1. 新建store的时候判断window.decToolsExtension
  2. 使用compose组合函数结合thunk和window.devToolsExtension
    1. import {createStore, applyMiddleware, compose} from 'redux'
    2.  
    3. const store = createStore(counter, compose(
    4. applyMiddleware(thunk),
    5. window.devToolsExtension ? window.devToolsExtension() : f => f
    6. ))
  3. 调试窗的redux选项卡,实时看到state

    使用React-redux优雅的链接react和redux

      

  • 安装react-redux

    1. npm install react-redux --save
  • 忘记subscribe,记住reducer,action和dispatch即可

  • React-redux提供Provider和connect两个接口来链接

  1. index.js中:Provider组件在应用最外层,传入store即可,只用一次

    1. import {Provider} from 'react-redux'
    2. import {counter} from './index.redux'
    3.  
    4. ReactDOM.render(
    5. <Provider store={store}>
    6. <App />
    7. </Provider>,
    8. document.getElementById('root')
    9. ); 
  2. Connect负责从外部获取组件需要的参数(mapStateToProps, actionCreators)

    1. import React from 'react';
    2. import {connect} from 'react-redux'
    3. import {addGUN, removeGUN, addGunAsync } from './index.redux'
    4.  
    5. class App extends React.Component{
    6. render(){
    7. return (
    8. <div>
    9. <h3>现在有机枪{this.props.num}把</h3>
    10. <button onClick={this.props.addGUN}>申请武器</button>
    11. <button onClick={this.props.removeGUN}>上交武器</button>
    12. <button onClick={this.props.addGunAsync}>拖两天再给</button>
    13. </div>
    14. )
    15. }
    16. }
    17.  
    18. const mapStateToProps = (state) => {
    19. return {
    20. num: state
    21. }
    22. }
    23. const actionCreators = {addGUN, removeGUN, addGunAsync}
    24.  
    25. App = connect(mapStateToProps, actionCreators)(App)
    26. export default App;  
  • Connect可以用装饰器的方式来优化

  1. 弹出个性化配置

    1. npm run eject
  2. 安转专门支持装饰器的插件

    1. npm install babel-plugin-transform-decorators-legacy --save-dev
  3. Package.json里babel加上plugins配置

    1. "plugins": [
    2. ["@babel/plugin-proposal-decorators", { "legacy": true }],
    3. ]  
  4. 优化connect

    1. import React from 'react';
    2. import {connect} from 'react-redux'
    3. import {addGUN, removeGUN, addGunAsync } from './index.redux'
    4.  
    5. @connect(
    6. state => ({num: state})
    7. {addGUN, removeGUN, addGunAsync}
    8. ) //使用装饰器方法优化connect
    9.  
    10. class App extends React.Component{
    11. render(){
    12. return (
    13. <div>
    14. <h3>现在有机枪{this.props.num}把</h3>
    15. <button onClick={this.props.addGUN}>申请武器</button>
    16. <button onClick={this.props.removeGUN}>上交武器</button>
    17. <button onClick={this.props.addGunAsync}>拖两天再给</button>
    18. </div>
    19. )
    20. }
    21. }
    22.  
    23. export default App;  

三、React-router4基础知识

    React-router4

  • React官方推荐路由库,4是最新版本,和之前版本不兼容,浏览器和RN均兼容
  • React开发单页应用必备,践行路由即组件的概念
  • 核心概念:动态路由、Route、Link、Switch
  • Web中应用React-router:安装react-router-dom作为前端路由

    1. npm install react-router-dom --save
  • 入门组件

  1. BrowserRouter包裹整个应用

  2. Router路由对应渲染的组件,可嵌套

  3. Link跳转专用

    1. import React from 'react';
    2. import ReactDOM from 'react-dom';
    3. import {BrowserRouter, Route, Link} from 'react-router-dom'
    4.  
    5. function Yiying(){
    6. return <h2>一营</h2>
    7. }
    8.  
    9. function Erying(){
    10. return <h2>二营</h2>
    11. }
    12.  
    13. function Qibinglian(){
    14. return <h2>骑兵连</h2>
    15. }
    16.  
    17. ReactDOM.render(
    18. <Provider store={store}>
    19. <BrowserRouter>
    20. <div>
    21. <ul>
    22. <li>
    23. <Link to='/'>一营</Link> //点击跳到指定路由
    24. </li>
    25. </ul>
    26. <ul>
    27. <li>
    28. <Link to='/erying'>二营</Link>
    29. </li>
    30. </ul>
    31. <ul>
    32. <li>
    33. <Link to='/qibinglian'>骑兵连</Link>
    34. </li>
    35. </ul>
    36. <Route path='/' exact component={Yiying}></Route> //exact表明路由完全匹配
    37. <Route path='/erying' component={Erying}></Route>
    38. <Route path='/qibinglian' component={Qibinglian}></Route> //路由对应渲染模板
    39. </div>
    40. </BrowserRouter>
    41. </Provider>,
    42. document.getElementById('root')
    43. );  
  • 其它组件
  1. url参数,Route组件参数可用冒号标识参数

    1. <Route path='/:location' component={Test}></Route> 
  2. Redirect组件  跳转
    1. <Redirect to='/qibinglian'></Redirect>  
  3. Switch只渲染命中的第一个子Route组件
    1. <Switch>
    2. <Route path='/' exact component={Yiying}></Route>
    3. <Route path='/erying' component={Erying}></Route>
    4. <Route path='/qibinglian' component={Qibinglian}></Route>
    5. </Switch>

    和Redux配合

  • 复杂redux应用,多个reducer,用combineReducers合并
  1. index.js中:引入合并后的reducer,并注入createStore中

    1. import reducers from './reducer' //合并后的reducer
    2.  
    3. const store = createStore(reducers, compose(
    4. applyMiddleware(thunk),
    5. window.devToolsExtension ? window.devToolsExtension() : f => f
    6. ))
  2. reducers.js中:合并所有reducer,并返回

    1. /**
    2. * 合并所有reducer 并且返回
    3. */
    4. import {combineReducers} from 'redux'
    5. import {counter} from './index.redux'
    6. import {auth} from './Auth.redux'
    7.  
    8. export default combineReducers({counter, auth})   
  • Redirect组件 跳转

    1. return this.props.isAuth ? app : <Redirect to='/login'></Redirect>  
  • Switch只渲染一个子Route组件

    1. ReactDOM.render(
    2. <Provider store={store}>
    3. <BrowserRouter>
    4. <Switch>
    5. <Route path='/login' component={Auth}></Route>
    6. <Route path='/dashboard' component={Dashboard}></Route>
    7. <Redirect to='/dashboard'></Redirect>
    8. </Switch>
    9. </BrowserRouter>
    10. </Provider>,
    11. document.getElementById('root')
    12. );  

      


注:转载请注明出处

【温故知新】—— React/Redux/React-router4基础知识&独立团Demo的更多相关文章

  1. React:快速上手(1)——基础知识

    React:快速上手(1)——基础知识 React(有时叫React.js或ReactJS)是一个为数据提供渲染为HTML视图的开源JavaScript库,用于构建用户界面. JSX.元素及渲染 1. ...

  2. React学习笔记(一) 基础知识

    现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我. React的基 ...

  3. Redux学习笔记-基础知识

      Redux概述 是什么:Redux是管理状态的容器,提供可预测的状态管理. 怎么做:Redux主要是用来管理组件或者应用的状态,本质上跟一个事件处理器差不多.通过分发action触发reduce来 ...

  4. NDK开发—基础知识实战Demo

    简介 前面写了几篇NDK相关的文章: NDK开发-简介&环境搭建(Eclipse,Android Studio) NDK开发-Android Studio+gradle-experimenta ...

  5. React Native 入门基础知识总结

    中秋在家闲得无事,想着做点啥,后来想想,为啥不学学 react native.在学习 React Native 时, 需要对前端(HTML,CSS,JavaScript)知识有所了解.对于JS,可以看 ...

  6. react + redux 完整的项目,同时写一下个人感悟

    先附上项目源码地址和原文章地址:https://github.com/bailicangd... 做React需要会什么? react的功能其实很单一,主要负责渲染的功能,现有的框架,比如angula ...

  7. Flutter调研(1)-Flutter基础知识

    工作需要,因客户端有部分页面要使用flutter编写,需要QA了解一下flutter相关知识,因此,做了flutter调研,包含安装,基础知识与demo编写,第二部分是安装与环境配置. —— Flut ...

  8. Flux --> Redux --> Redux React 基础实例教程

    本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...

  9. Flux --> Redux --> Redux React 入门 基础实例使用

    本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...

随机推荐

  1. BZOJ2743 [HEOI2012]采花 【离线 + 树状数组】

    题目 萧芸斓是Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于公主采 ...

  2. 从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

    转载自:http://blog.csdn.net/v_july_v/article/details/8203674/ 从K近邻算法.距离度量谈到KD树.SIFT+BBF算法 前言 前两日,在微博上说: ...

  3. stringutil的方法

    StringUtils 源码,使用的是commons-lang3-3.1包. 下载地址 http://commons.apache.org/lang/download_lang.cgi 以下是Stri ...

  4. RSA加密/解密 Decryption error异常解决

    RSA加密/解密 Decryption error异常解决 import java.io.ByteArrayOutputStream; import java.security.Key; import ...

  5. AngularJS 作用域与数据绑定机制

    AngularJS 简介 AngularJS 是由 Google 发起的一款开源的前端 MVC 脚本框架,既适合做普通 WEB 应用也可以做 SPA(单页面应用,所有的用户操作都在一个页面中完成).与 ...

  6. C#操作XML序列化与反序列化

    public class XmlSerializerHelper { /// <summary> /// 从XML文件中反序列化读取对象 /// </summary> /// ...

  7. Flask-Migrate拓展数据库表结构

    # 转载请留言联系 在我们用 sqlchemy 模块创建完几个表时,如果在实际生产环境中,需要对表结构进行更改,应该怎么办呢?总不能把表删除了吧,这样数据就会丢失了. 更好的解决办法是使用数据库迁移框 ...

  8. JS基础用法-向数组指定位置插入对象

    在做省市区三级联动的时候,需要在省市区默认位置放上请选择字样. 由于后台的API接口返回的没有请选择字样,那么就需要给返回的数组手动增加请选择 代码如下 // 原来的数组 var array = [& ...

  9. 设计模式之不变模式(Immutable Pattern)分析

    http://www.iteye.com/topic/959751 最近老有人问我不变模式,我其实也理解得不深,于是花了一些时间进行学习总结,分析了一下不变模式(immutable pattern), ...

  10. Maximum Size Subarray Sum Equals k -- LeetCode

    Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If t ...