使用react+redux+react-redux+react-router+axios+scss技术栈从0到1开发一个applist应用
先看效果图

github地址
初始化项目
#创建项目
create-react-app applist
#如果没有安装create-react-app的话,先安装
npm install -g create-react-app
目录结构改造
|--config
|--node_modules
|--public
|--scripts
|--src
    |-----api   //api接口
    |-----components  //组件
    |-----pages  //页面
    |-----plugins   //插件相关 axios
    |-----router  //路由
    |-----store   //redux
    |-----styles   //公共样式
    |-----utils   //工具包
    |-----index.js   //入口
|--package.json
Vscode插件安装
所谓工欲善其事,必先利其器。这里我们推荐一些好用的vscode插件


1. 代码提示类插件
1.1 Reactjs code snippets
1.2 React Redux ES6 Snippets
1.3 React-Native/React/Redux snippets for es6/es7
1.4 JavaScript (ES6) code snippets(es6代码片段)
1.5 Typescript React code snippets(这是tsx的react组件片段)
2. 美化类插件
2.1 One Dark Pro(atom风格主题)
2.2 vscode-icons(文件图标)
3. 其他实用类插件
3.1 Beautify css/sass/scss/less(样式代码格式化)
3.2 npm Intellisense(对package.json内中的依赖包的名称提示)
3.3 Path Intellisense(文件路径补全)
3.4 cssrem(px转换为rem)
3.5 CSS Modules(对使用了css modules的jsx标签的类名补全和跳转到定义位置)
4.vscode配置设备同步
Settings Sync
有了它就不用每次换个开发环境又重新配置一遍vscode了
5.另外,react的jsx补全html标签需要在vscode单独设置一下
首选项-设置-搜索‘includeLanguages’-编辑settings.json添加如下代码即可
"emmet.includeLanguages": {
        "javascript": "javascriptreact"
    }
最后,安装完插件之后,以下两个快捷键可能会经常使用
rcc 生成有状态的组件代码块
rfc 生成无状态的组件代码块
使用axios插件请求数据并封装api请求
1、安装
npm isntall axios --save
2、创建axios.js文件
主要是用来创建axios实例,添加请求拦截,全局处理一些业务逻辑,例如全局loading展示,返回状态码处理等 。
具体的配置可查看axios
3、创建api目录,并新建index.js文件
import axios from '../plugins/axios';
let api = {
  // app列表
  appListData(params){
    return axios.get('/mock/appListData.json', params);
  },
  // 推荐
  recommendData(params) {
    return axios.get('/mock/recomendData.json', params);
  },
  // 搜索
  lookUp(params) {
    return axios.get('/mock/lookUp.json', params);
  }
}
export default api
4、组件中使用
import $api from '../api/index.js';
$api.recommendData({}).then((response) => {
      let feed = response.feed;
      this.setState({
        recommendList: feed.entry
      })
    }).catch(err => {
      console.log(err)
    })
axios拦截器添加全局loading,多个请求合并一个loading
通过配置axios的过滤器,可以拦截用户请求,我们在这里添加全局loading,返回时在隐藏loading的显示。这里有个问题需要解决的是,如果同一时刻我们发起多个请求,那么会出现多个loading的问题,解决办法就是,通过设定一个count变量来记录当前接口请求数量,当count为0时再结束loading。
showFullScreenLoading、tryHideFullScreenLoading要干的事儿就是将同一时刻的请求合并,声明一个变量needLoadingRequestCount,每次调用showFullScreenLoading方法 needLoadingRequestCount + 1。调用tryHideFullScreenLoading()方法,needLoadingRequestCount - 1。needLoadingRequestCount为 0 时,结束 loading。
另外还可以通过参数形式设定不需要显示loading的请求,在拦截处通过判断来显示
1、在common.js文件中添加如下代码
import { Toast } from 'antd-mobile'
/**
 * 显示loading
 */
function showLoading(){
  Toast.loading('加载中...', 0);
}
/**
 * 隐藏loading
 */
function hideLoading(){
  Toast.hide();
}
/**
 * 合并请求,同一时刻只显示一个loading
 */
let needLoadingRequestCount = 0
export function showFullScreenLoading() {
  if (needLoadingRequestCount === 0) {
    showLoading()
  }
  needLoadingRequestCount++
}
export function hideFullScreenLoading() {
  if (needLoadingRequestCount <= 0){
    return
  }
  needLoadingRequestCount--
  if (needLoadingRequestCount === 0) {
    hideLoading()
  }
}
2、在axios中使用
import { showFullScreenLoading, hideFullScreenLoading} from '../utils/commons'
// Add a request interceptor
_axios.interceptors.request.use(function (config) {
  // Do something before request is sent
  showFullScreenLoading();
  return config;
}, function (error) {
  // Do something with request error
  return Promise.reject(error);
});
// Add a response interceptor
_axios.interceptors.response.use(function (response) {
  // Do something with response data
  setTimeout(() => {
    hideFullScreenLoading();
  }, 1000);
  return response.data;
}, function (error) {
  // Do something with response error
  return Promise.reject(error);
});
配置react-router
在React中,常用的有两个包可以实现这个需求,那就是react-router和react-router-dom,这两个不同之处就是后者比前者多出了 这样的 DOM 类组件,所以我们只需要使用react-router-dom就可以了
1、安装
npm install react-router-dom --save-dev
2、创建路由组件router/index.js
import React from 'react';
import { HashRouter, Route, Switch } from 'react-router-dom';
import Home from '../pages/Home';
import Profile from '../pages/profile/Profile';
const BasicRoute = () => (
  <HashRouter>
    <Switch>
      <Route exact path="/" component={Home} />
      <Route exact path="/profile" component={Profile} />
    </Switch>
  </HashRouter>
);
export default BasicRoute;
将两个页面组件Home和Detail使用Route组件包裹,外面套用Switch作路由匹配,当路由组件检测到地址栏与Route的path匹配时,就会自动加载响应的页面
3、入口文件index.js引入router组件
import React from 'react';
import ReactDOM from 'react-dom';
import Router from './router/router';
ReactDOM.render(
  <Router/>,
  document.getElementById('root')
);
4、路由跳转
this.props.history.push("/search/result");
添加vw适配手机屏幕
1、默认webpack的配置是隐藏的,通过eject 显示webpack配置(此操作不可逆)
npm run eject  
2、安装postcss
npm install --save postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano
3、webpack配置
修改webpack.config.js,添加如下代码:
{
        // Options for PostCSS as we reference these options twice
        // Adds vendor prefixing based on your specified browser support in
        // package.json
        loader: require.resolve('posREtcss-loader'),
        options: {
          // Necessary for external CSS imports to work
          // https://github.com/facebook/create-react-app/issues/2677
          ident: 'postcss',
          plugins: () => [
            require('postcss-flexbugs-fixes'),
            require('postcss-preset-env')({
              autoprefixer: {
                flexbox: 'no-2009',
              },
              stage: 3,
            }),
            // Adds PostCSS Normalize as the reset css with default options,
            // so that it honors browserslist config in package.json
            // which in turn let's users customize the target behavior as per their needs.
            postcssNormalize(),
            // 添加vw配置 start
            postcssAspectRatioMini({}),
            postcssPxToViewport({
              viewportWidth: 750, // (Number) The width of the viewport.
              viewportHeight: 1334, // (Number) The height of the viewport.
              unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to.
              viewportUnit: 'vw', // (String) Expected units.
              selectorBlackList: ['.ignore', '.hairlines', '.list-row-bottom-line', '.list-row-top-line'], // (Array) The selectors to ignore and leave as px.
              minPixelValue: 1, // (Number) Set the minimum pixel value to replace.
              mediaQuery: false // (Boolean) Allow px to be converted in media queries.
            }),
            postcssWriteSvg({
              utf8: false
            }),
            postcssPresetEnv({}),
            // postcssViewportUnits({
            //  filterRule: rule => rule.selector.indexOf('::after') === -1 && rule.selector.indexOf('::before') === -1 && rule.selector.indexOf(':after') === -1 && rule.selector.indexOf(':before') === -1
            // }),
            postcssViewportUnits({}),
            cssnano({
              "cssnano-preset-advanced": {
                zindex: false,
                autoprefixer: false
              },
            })
            // 添加vw配置 end
          ],
          sourceMap: isEnvProduction && shouldUseSourceMap,
        },
      },
这里,配置之后运行项目会发现有个报错
ReferenceError: postcssPresetEnv is not defined
是因为我们没有引入postcssPresetEnv
安装并添加以下依赖
npm install postcss-preset-env --save-dev
const postcssPresetEnv = require('postcss-preset-env');
配置好了之后,再访问我们的页面,可以发现已经自动转成vw了
4、兼容低版本android,加入viewport-units-buggyfill hack
下载viewport-units-buggyfill.min.js到public文件夹下面,修改index.html添加如下代码:
<script src='%PUBLIC_URL%/viewport-units-buggyfill.min.js'></script>
    <script>
      window.onload = function () {
        window.viewportUnitsBuggyfill.init({
          hacks: window.viewportUnitsBuggyfillHacks
        });
      }
    </script>
或者使用cdn的方式引入
<script src="//g.alicdn.com/fdilab/lib3rd/viewport-units-buggyfill/0.6.2/??viewport-units-buggyfill.hacks.min.js,viewport-units-buggyfill.min.js"></script>
安装scss
npm install node-sass sass-loader --save
在React中的几种样式写法
行内样式、声明样式、引入样式、CSS Modules模块化
1、行内样式
<div style={{ background: '#eee', width: '200px', height: '200px'}}>
        <p style= {{color:'red', fontSize:'40px'}}>行内样式</p>
      </div>
2、声明样式
const style1={
      background:'#eee',
      width:'200px',
      height:'200px'
    }
<div style={style1}>
        <p style= {style2}>行内样式</p>
      </div>
3、引入样式
.person{
    width: 60%;
    margin:16px auto;
}
import './Person.css';
<div className='person'>
        <p>person:Hello world</p>
      </div>
4、css module
CSS Modules 的做法就是通过配置将.css文件进行编译,编译后在每个用到css的组件中的css类名都是独一无二的,从而实现CSS的局部作用域。
在create-react-app2.0之前的版本,配置CSS Modules是需要eject弹出webpack来配置的,幸运的是,create-react-app自从2.0.版本就已经开始支持CSS Modules了
(1)局部样式
命名规则: xxx.module.css     
                 引入方式 import xxx from 'xxx.module.css'
                  用法:<div className={xxx.styleName}>
(2)全局样式
命名规则: xxx.css   
                   引入方式 import ‘xxx.css’
                   用法:<div className='styleName'>
全局样式与局部样式混合使用:
<div className={`styleName ${xxx['styleName']}`} >
其中styleName表示全局样式  ${xxx['styleName']表示局部样式,注意{ }内使用模板字符串 ·
5、css多类名写法
(1) css module模块中写法
<div className={[`${styles.sideInBox}`,`${styles.sideTitleBox}`].join(' ')}></div>
(2) 如果是全局样式写法
className={`title ${index === this.state.active ? 'active' : ''}`}
React条件渲染的几种方式
参考https://www.cnblogs.com/xiaodi-js/p/9119826.html
1、条件表达式
<div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleLogoutClick} />
      ) : (
        <LoginButton onClick={this.handleLoginClick} />
      )}
    </div>
2、&&操作符
<div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
    </div>
3、列表遍历
jxs的语法,js代码要放在{}里面,html标签使用return ()包裹
return (
            <div className='appList-container'>
                <ul className='list'>
                    {
                        this.props.list.map((item, index) => {
                            return (
                                <li className='list-item' key={index}>
                                    <div className='app-index'>{index+1}</div>
                                    <img className='app-icon' src={item['im:image'][0].label} alt="" />
                                    <div className='app-info'>
                                        <div className='app-name'>{item['im:name'].label}</div>
                                        <div className='app-categray'>{item.category.attributes.label}</div>
                                    </div>
                                </li>
                            )
                        })
                    }
                </ul>
            </div>
        );
事件处理
<button onClick={this.handleClick}>ck me
      </button>
两种事件传参方式
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
获取input表单值
两种方法,受控组件和非受控组件。
推荐使用受控组件,即通过this.state获取,因为其符合react规范;
非受控组件,给标签指定ref属性
<input className='search-bar' type="text" ref='keyword' onKeyUp={this.appSearch.bind(this)}>
appSearch(e){
        let keyword = this.refs.keyword.value
    }
react中使用防抖
appSearch = debounce(() => {
    }, 500);
组合组件
参考https://www.jianshu.com/p/0b005dc60bda
在react开发中,在某些场景会遇到如下组件嵌套形式的开发,例如group和cell或者RadioGroup、RadioOption
<RadioGroup name="option">
    <RadioOption label="选项一" value="1" />
    <RadioOption label="选项二" value="2" />
  </RadioGroup>,
state定义及赋值
constructor(props) {
    super(props);
    this.state = {
      appList:[]
    };
  }
this.setState({
        appList: feed.entry
      })
父子组件传参
1、父传子
<AppList list={this.state.appList}></AppList>
在子组件获取值
this.props.list
2、子传父
触发父组件事件
        this.props.appSearch(keyword);
父组件监听事件
 <Search appSearch={this.appSearch.bind(this)}></Search>
引入redux和react-redux、redux-thunk
文档
https://react-redux.js.org/introduction/quick-start
http://cn.redux.js.org/docs/introduction/ThreePrinciples.html
类似vuex,redux是一个数据状态管理工具,但是用法和vuex有些区别
react-redux帮助你完成数据订阅,redux-thunk可以放你实现异步action,redux-logger是redux的日志中间件
redux-thunk 是一个比较流行的 redux 异步 action 中间件。redux-thunk 帮助你统一了异步和同步 action 的调用方式,把异步过程放在 action 级别解决,对 component 没有影响
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
// 创建store的时候,第二个参数是中间件,redux-thunk提供了一个thunk中间件,用于处理异步的action
export default createStore(
  rootReducer,
  applyMiddleware(thunk)
);
1、对redux的理解
(1)单一数据源:
整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中
(2)State只读:
唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象
(3)执行修改:
为了描述 action 如何改变 state tree ,你需要编写 reducers
Reducer 只是一些纯函数,它接收先前的 state 和 action,并返回新的 state
随着应用变大,你可以把它拆成多个小的 reducers,分别独立地操作 state tree 的不同部分
2、对mapStateToProps和mapDispatchToProps的理解
使用 React Redux 库的 connect() 方法来生成容器组件前,需要先定义 mapStateToProps 这个函数来指定如何把当前 Redux store state 映射到展示组件的 props 中。
除了读取 state,容器组件还能分发 action。类似的方式,可以定义mapDispatchToProps() 方法接收 dispatch() 方法并返回期望注入到展示组件的 props 中的回调方法。它可以是一个函数,也可以是一个对象。
// 将state 映射到展示组件的 props 中
const mapStateToProps = state => {
  return {
    searchList: state.searchList
  }
}
const mapDispatchToProps = dispatch => {
  return {
    saveSearchList: searchList => dispatch(saveSearchList(searchList))
  }
}
// export default SearchResult;
// 通过connect生成容器组件
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(SearchResult)
3、安装redux react-redux redux-thunk
npm install --save redux react-redux redux-thunk
npm install --save-dev redux-logger
4、使用react-hot-loader实现局部热更新
#安装
npm install --save-dev react-hot-loader
#使用
import { AppContainer } from 'react-hot-loader';
import Route from './router/';
const render = Component => {
ReactDOM.render(
    <AppContainer>
        <Component />
    </AppContainer>,
    document.getElementById("root"));
}
render(Route);
引入antd-mobile移动端UI框架
antd-mobile文档
https://mobile.ant.design/index-cn
1、安装依赖
npm install antd-mobile --save
2、安装 babel-plugin-import
npm install babel-plugin-import --save
3、在 package.json 配置 antd-mobile 的按需加载(在babel下添加)
"plugins": [
    [
      "import",
      {
        "libraryName": "antd-mobile",
        "style": "css"
      }
    ]
  ],
4、组件中使用
import { Toast,Button } from 'antd-mobile'
<Button type="primary">primary</Button>
上拉刷新及加载更多
这里使用react-pullload这个库
1、安装
npm install --save react-pullload
2、使用
import ReactPullLoad, { STATS } from "react-pullload";
import "react-pullload/dist/ReactPullLoad.css";
constructor(props) {
    super(props);
    this.state = {
      appList: [],
      appListAll: [],
      recommendList:[],
      hasMore: true,
      action: STATS.init,
      pageSize:10,
      page:1
    };
  }
handleAction = action => {
    //new action must do not equel to old action
    if (action === this.state.action) {
      return false;
    }
    if (action === STATS.refreshing) {
      this.handRefreshing();
    } else if (action === STATS.loading) {
      this.handLoadMore();
    } else {
      //DO NOT modify below code
      this.setState({
        action: action
      });
    }
  };
  // 刷新
  handRefreshing = ()=>{
    this.setState({
      action: STATS.refreshing
    });
    this.getAppList();
  }
  // 加载更多
  handLoadMore = ()=>{
    if (STATS.loading === this.state.action) {
      return false;
    }
    //无更多内容则不执行后面逻辑
    if (!this.state.hasMore) {
      return;
    }
    // 显示正在加载
    this.setState({
      action: STATS.loading
    });
    let page = this.state.page+1;
    setTimeout(() => {
      this.getPageData(page);
    }, 1500);
  }
render() {
    return (
      <div className='container'>
        <div className='search-bar'>
          <Search onFoucs={this.onFoucs.bind(this)}></Search>
        </div>
        <ReactPullLoad
          className="block"
          isBlockContainer={true}
          downEnough={100}
          action={this.state.action}
          handleAction={this.handleAction}
          hasMore={this.state.hasMore}
          distanceBottom={100}>
          <Recommend list={this.state.recommendList}></Recommend>
          <AppList list={this.state.appList}></AppList>
        </ReactPullLoad>
      </div>
    );
  }
因为是使用的mock数据,获取的是全部数据,所以这里采用前端分页的方式加载更多
// 分页加载
  getPageData(page){
    let resultList = [], list = [];
    let appListAll = this.state.appListAll;
    let pageSize = this.state.pageSize;
    let totalPage = Math.ceil(appListAll.length / pageSize);//总页数
    let startIndex = pageSize * (page - 1);
    let endIndex = pageSize * page;
    for (let i = startIndex; i < endIndex; i++) {
      resultList.push(appListAll[i]);
    }
    if (page >= totalPage){
      this.setState({ hasMore: false});
    }
    if (page===1){
      list = resultList;
    }else{
      list = this.state.appList.concat(resultList);
    }
    this.setState({
      appList: list,
      page: page,
      pageSize: pageSize,
      action: STATS.reset
    })
  }
图片懒加载
http://npm.taobao.org/package/react-lazy-load
1、安装
npm install --save react-lazy-load
2、使用
import LazyLoad from 'react-lazy-load';
<LazyLoad offsetVertical={100}>
  <img className='app-icon' src={item['im:image'][0].label} alt="" />
</LazyLoad>
问题总结
1、在react中进入页面自动获取input输入焦点 ,弹出键盘
input中设置ref属性(非受控组件),通过 this.refs.keyword调用
<input className='search-input' type="text" ref='keyword' onChange={this.appSearch.bind(this)} onFocus={this.onFoucs.bind(this)} placeholder="搜索应用" />
也可以写成ref={(input) => { this.textInput = input; }}方式
<input type="text" ref={(input) => { this.textInput = input; }} />
使用this.textInput.focus();方式调用
钩子函数中中调用
componentDidMount(){
  this.refs.keyword.focus();
    }
2、父组件调用子组件方法(搜索组件,有两个地方使用到,首页和搜索页,其中首页不需要自动获取焦点,进入搜索页时需要自动获取焦点)
通过在搜索结果页里面获取搜索子组件的实例并调用foucs方法进行聚焦,从而不影响其他使用搜索组件的父组件状态
(1)子组件中定义foucs方法
focus(){
        this.refs.keyword.focus();
    }
(2)设置input的ref属性
<input className='search-input' type="text" ref='keyword' onChange={this.appSearch.bind(this)} onFocus={this.onFoucs.bind(this)} placeholder="搜索应用" />
(3)父组件中调用foucs方法
componentDidMount(){
    this.manualFocusInst.focus();
  }
<Search appSearch={this.appSearch.bind(this)} ref={(ref)=>this.manualFocusInst = ref} onCancel={this.onCancel.bind(this)} onFoucs={this.onFoucs.bind(this)} showCancelBtn={true}></Search>
3、react build的时候报错
throw new BrowserslistError('Unknown browser query `' + selection + '`')
解决办法是找到packpage.json里的browserslist,然后修改
"browserslist": [
    "last 2 versions",
    "android 4",
    "opera 12"
  ],
build开启静态服务访问
 npm install -g serve
 serve -s build
4、组件上面不能直接添加className,如
解决方式使用一个父div进行包裹
<div className='search-bar'>
          <Search onFoucs={this.onFoucs.bind(this)}></Search>
        </div>
5、ios 系统下img不显示问题,解决方案如下:
/*兼容ios不显示图片问题*/
img {
    content: normal !important
}
6、1px问题,解决方案
/*伪元素1px*/
.row-cell:before {
    content: " ";
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    height: 1px;
    border-top: 1px solid #e5e5e5;
    color: #e5e5e5;
    transform-origin: 0 0;
    transform: scaleY(0.5);
    z-index: 2;
}
相关文档
https://react.docschina.org/
https://www.redux.org.cn/
https://react-redux.js.org/
http://react-guide.github.io/react-router-cn
https://mobile.ant.design
最后
代码我已经提交到github上去了,如果觉得还可以,欢迎star或者fork
参考阅读
https://www.jianshu.com/p/8954e9fb0c7e
https://blog.csdn.net/z9061/article/details/84619309
https://www.jianshu.com/p/f97aa775899f
https://www.cnblogs.com/jack-liu6/p/9927336.html
使用react+redux+react-redux+react-router+axios+scss技术栈从0到1开发一个applist应用的更多相关文章
- Vue2.0+Webpack+Element+Axios+vueRouter技术栈使用过程总结
		搭建项目架构 目采用Webpack+Vue-router的架构方式,开始安装(一切操作都在windows系统上完成) 1.按Win+R,然后在文本框中输入cmd,回车打开命令行,输入vue-cli安装 ... 
- 用react系列技术栈实现的demo整合系统
		引子 学生时代为了掌握某个知识点会不断地做习题,做总结,步入岗位之后何尝不是一样呢?做业务就如同做习题,如果‘课后’适当地进行总结,必然更快地提升自己的水平. 由于公司采用的react+node的技术 ... 
- react+redux+webpack+git技术栈
		一.git bash here mdkr cnpm init -y ls -a ls -l ls -la隐藏的也可查看 cat package.json 二.npm npm i webpack-dev ... 
- React项目使用Redux
		⒈创建React项目 初始化一个React项目(TypeScript环境) ⒉React集成React-Router React项目使用React-Router ⒊React集成Redux Redux ... 
- React,关于redux的一点小见解
		最近项目做多页面应用使用到了,react + webpack + redux + antd去构建多页面的应用,本地开发用express去模拟服务端程序(个人觉得可以换成dva).所以在这里吐槽一下我自 ... 
- 在React中使用Redux
		这是Webpack+React系列配置过程记录的第六篇.其他内容请参考: 第一篇:使用webpack.babel.react.antdesign配置单页面应用开发环境 第二篇:使用react-rout ... 
- react系列(五)在React中使用Redux
		上一篇展示了Redux的基本使用,可以看到Redux非常简单易用,不限于React,也可以在Angular.Vue等框架中使用,只要需要Redux的设计思想的地方,就可以使用它. 这篇主要讲解在Rea ... 
- React Native集成Redux框架讲解与应用
		学过React Native的都知道,RN的UI是根据相应组件的state进行render的,而页面又是由大大小小的组件构成,导致每个组件都必须维护自身的一套状态,因此当页面复杂化的时候,管理stat ... 
- React学习之redux
		在阅读本文之前,希望大家对以下知识点能提前有所了解并且上好厕所(文章有点长): 状态提升的概念 react高阶组件(函数) es6基础 pure 组件(纯函数) Dumb 组件 React.js的co ... 
随机推荐
- ASP UserInfoList 方法1
			<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UserInfoList.a ... 
- AY写给国人的教程- VS2017 Live Unit Testing[2/2]-C#人爱学不学-aaronyang技术分享
			原文:AY写给国人的教程- VS2017 Live Unit Testing[2/2]-C#人爱学不学-aaronyang技术分享 谢谢大家观看-AY的 VS2017推广系列 Live Unit Te ... 
- SQLServer 不允许保存更改的解决办法
			启动SQL Server Management Studio 工具菜单----选项----Designers(设计器)----阻止保存要求重新创建表的更改 取消勾选即可. 
- Win8Metro(C#)数字图像处理--2.20图像垂直镜像
			原文:Win8Metro(C#)数字图像处理--2.20图像垂直镜像  [函数名称] 图像垂直镜像函数MirrorYProcess(WriteableBitmap src) [函数代码] ... 
- 【shell】分享高通平台刷版本简单的一个shell脚本
			#!/bin/shadb wait-for-deviceadb reboot bootloaderecho "start download"wait 5sudo fastboot ... 
- Android零基础入门第18节:EditText的属性和使用方法
			原文:Android零基础入门第18节:EditText的属性和使用方法 EditText与TextView非常相似,它甚至与TextView 共用了绝大部分XML属性和方法.EditText与Tex ... 
- [转载]关于Java reference的一篇博文
			不再额外的叨叨了,直接附上原地址: https://community.oracle.com/people/enicholas/blog/2006/05/04/understanding-weak-r ... 
- UWP -- Background Task 深入解析
			原文:UWP -- Background Task 深入解析 1. 重点 锁屏问题 从 Windows 10 开始,用户无须再将你的应用添加到锁屏界面,即可利用后台任务,通用 Windows 应用必须 ... 
- Tcptrack —— TCP 连接的嗅探器
			分享 <关于我> 分享 [中文纪录片]互联网时代 http://pan.baidu.com/s/1qWkJfcS 分享 <HTML开发MacOSAp ... 
- 国外优秀的UI设计资源库收集
			国外优秀的UI设计资源库 网站设计或者说UI设计对于Web上的运用是非常的关键,一个站做得好不好,能不能吸引人的眼球,设计占了不低的地位,但话又说回来,Web前端人员又有多少人是设计专业毕业,具有这方 ... 
