资源:create-react-app、react、react-dom、redux、react-redux、redux-thunk、react-router-dom、antd-mobile/antd、lib(scss库)、axios/fetch

一、创建项目(首先确保你的电脑中装有create-react-app这个脚手架,如果没有,可以通过npm命令安装,或者使用后续大勋提供的项目源码)

create-react-app my-react-app

项目创建完毕,我们需要抽离配置文件,以便于可以后期合作开发

二、抽离配置文件

cd  my-react-app

cnpm run eject

一定要选择输入y

三、项目配置

1、删除src文件夹下除了registerServiceWorker.js和index.js之外的所有的文件

2、增加components、lib(scss库)、store、router、tool、api这些文件夹

3、创建App.jsx,修改config/webpack.config.dev.js和webpack.config.prod.js,添加@符号,让它指向src目录

App.jsx

import React, {Component} from 'react'

export default class App extends Component {

render () {

return (

<div>app</div>

)

}

}

webpack.config.dev.js的第87行

webpack.config.prod.js的第93行

4、在src/index.js中引入App.jsx组件,测试组件可用性,运行cnpm run start测试

import React from 'react';

import ReactDOM from 'react-dom';

import App from '@/components/App';

import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

registerServiceWorker();

5、引入错误边界异常处理,components/ErrorBoundary.jsx

import React, {Component} from 'react'

class ErrorBoundary extends Component {

constructor(props) {

super(props);

this.state = { hasError: false };

}

componentDidCatch(error, info) {

this.setState({ hasError: true });

}

render() {

if (this.state.hasError) {

return <h1>Something went wrong.</h1>;

}

return this.props.children;

}

}

export default ErrorBoundary

6、修改src/index.js

import React from 'react';

import ReactDOM from 'react-dom';

import App from '@/components/App';

import ErrorBoundary from '@/components/ErrorBoundary';

import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(

<ErrorBoundary>

<App />

</ErrorBoundary>

, document.getElementById('root'));

registerServiceWorker();

7、引入scss模块

cnpm i node-sass sass-loader -D

修改config/webpack.config.dev.js和webpack.config.prod.js,添加scss的配置

webpack.config.dev.js,在191-198行写入如下代码

webpack.config.prod.js,在515-222行写入如下代码

四、创建必须组件

因为项目中的组件我们需要将其分为容器组件和UI组件,所以此处我们先行引入react-redux模块,又因为react-redux需要redux配合使用,需要安装,如果你的项目中的组件需要有异步操作,那么需要使用到redux-thunk模块

cnpm i react-redux redux  redux-thunk -S

以首页为例,index.jsx为容器组件、ui.jsx为UI组件、store.js为该首页组件的reducer---用来提供状态

ui.jsx

import React, {Component} from 'react';

export default class UI extends Component {

render () {

return (

<div className = "container">

<div className = "box">页面内容</div>

<footer>页面底部</footer>

</div>

)

}

}

store.js,如果首页中有banner数据和prolist数据的话-----此处一定要记住写法

const reducer = (state = {banner: [1,2,3], prolist: []}, {type, data}) => {

const {banner, prolist} = state;

switch (type) {

case 'CHANGE_BANNER':

return {banner: data, prolist};

case 'CHANGE_PROLIST':

return {prolist: data, banner};;

default:

return state;

}

}

export default reducer;

在src文件夹下store下的index.js

import {createStore, combineReducers} from 'redux';

import home from '@/components/home/store';

const reducer = combineReducers({home});

const store = createStore(reducer);

export default store;

在入口文件处处理index.js

import React from 'react';

import ReactDOM from 'react-dom';

import {Provider} from 'react-redux';

import store from '@/store/index';

import App from '@/components/App';

import ErrorBoundary from '@/components/ErrorBoundary';

import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(

<Provider store = {store}>

<ErrorBoundary>

<App />

</ErrorBoundary>

</Provider>

, document.getElementById('root'));

registerServiceWorker();

index.jsx---容器组件

import UI from './ui';

import {connect} from 'react-redux';

const mapStateToProps = (state) => {

return {

banner: state.home.banner,

prolist: state.home.prolist

}

}

const mapDispatchToProps = (dispatch) => {

return {

}

}

const Com = connect(

mapStateToProps,

mapDispatchToProps

)(UI);

export default Com;

如果首页UI组件内部需要在组件装载完毕之后请求数据,又不希望在容器组件内部请求数据,需要用到异步请求模块redux-thunk

UI.jsx

import React, {Component} from 'react';

export default class UI extends Component {

compoentDidMount () {

this.props.getBannerList();

this.props.getProList();

}

render () {

return (

<div className = "container">

<div className = "box">页面内容</div>

<footer>页面底部</footer>

</div>

)

}

}

新建action.js

const getData = (url) => {

return new Promise((resolve, reject) => {

fetch(url).then(res => res.json()).then(data => resolve(data)).catch(err => reject(err))

})

}

export default {

getbannerlist (dispatch) {

getData('http://www.daxunxun.com/douban').then(data => {

dispatch({

type: 'CHANGE_BANNER',

data

})

})

},

getprolist (dispatch) {

getData('http://www.daxunxun.com/douban').then(data => {

dispatch({

type: 'CHANGE_PROLIST',

data

})

})

}

}

index.jsx --- 容器组件

import UI from './ui';

import {connect} from 'react-redux';

import action from './action';

import store from '@/store/index';

const mapStateToProps = (state) => {

//  console.log(state)

return {

banner: state.home.banner,

prolist: state.home.prolist

}

}

const mapDispatchToProps = (dispatch) => {

return {

getBannerList: () => {

//      console.log('1')

store.dispatch(action.getbannerlist)

},

getProList: () => {

store.dispatch(action.getprolist)

}

}

}

const Com = connect(

mapStateToProps,

mapDispatchToProps

)(UI);

export default Com;

最终,home组件结构如下

如法炮制,设置其他的一些组件,比如分类kind、购物车cart、用户中心user

五、设置路由模块

1、安装路由模块

cnpm i react-router-dom -S

2、创建路由模块router/index.js

import Home from '@/components/home/index';

import Kind from '@/components/kind/index';

import Cart from '@/components/cart/index';

import User from '@/components/user/index';

const routes = [

{

path: '/home',

component: Home

},

{

path: '/kind',

component: Kind

},

{

path: '/cart',

component: Cart

},

{

path: '/user',

component: User

}

]

export default routes;

3、程序入口地址修改index.js

import React from 'react';

import ReactDOM from 'react-dom';

import {Provider} from 'react-redux';

import store from '@/store/index';

import App from '@/components/App';

import ErrorBoundary from '@/components/ErrorBoundary';

import registerServiceWorker from './registerServiceWorker';

import {HashRouter as Router, Switch, Route} from 'react-router-dom';

function render(){

ReactDOM.render(

<Provider store = {store}>

<ErrorBoundary>

<Router>

<Switch>

<Route path = '/' component = {App} />

</Switch>

</Router>

</ErrorBoundary>

</Provider>

, document.getElementById('root'));

}

render();

store.subscribe(render);

registerServiceWorker();

4、修改App.jsx

import React, {Component} from 'react';

import routes from '@/router/index';

import {Switch, Route, Redirect} from 'react-router-dom';

export default class App extends Component {

render () {

return (

<div>

<Switch >

{

routes.map((item, index) => {

return (

<Route key={index} path={item.path} component = {item.component} />

)

})

}

<Redirect to={{pathname:'/home'}} />

</Switch>

</div>

)

}

}

5、地址栏输入相关路由测试可行性

6、路由跳转

6.1 声明式跳转

<Link>         -----  不含有样式----列表进入详情

<NavLink>   ----- 选中的路由会自带有一个active的样式 ---- 底部切换

import {NavLink, Link} from 'react-router-dom';

<NavLink to='/home'>首页</NavLink><Link to='/detail/123'>详情</Link>

6.2 编程式跳转 ---- 一定要注意写的地方

this.props.history.push('/home')

7、假设你的项目中有一些页面结构不一致的情况下,比如说详情页面有自己的底部,那么可以在入口文件处和App组件同样配置,index.js

import React from 'react';

import ReactDOM from 'react-dom';

import {Provider} from 'react-redux';

import store from '@/store/index';

import App from '@/components/App';

import Detail from '@/components/detail/index';

import ErrorBoundary from '@/components/ErrorBoundary';

import registerServiceWorker from './registerServiceWorker';

import {HashRouter as Router, Switch, Route} from 'react-router-dom';

function render(){

ReactDOM.render(

<Provider store = {store}>

<ErrorBoundary>

<Router>

<Switch>

<Route path = '/detail' component = {Detail} />

<Route path = '/' component = {App} />

</Switch>

</Router>

</ErrorBoundary>

</Provider>

, document.getElementById('root'));

}

render();

store.subscribe(render);

registerServiceWorker();

六、UI库的配置

pc:  cnpm i antd -S

mobile:  cnpm i antd-mobile -S

虽然UI组件库可以全部引入,但是我们还是强烈建议使用按需引入模式

cnpm i babel-plugin-import -D

cnpm i babel-preset-env babel-preset-react -D

创建一个.babelrc文件,写入如下内容

{

"presets": [

["env", {

"modules": false,

"targets": {

"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]

}

}],

"react"

],

"plugins": [

["import", { "libraryName": "antd-mobile", "style": "css" }]

]

}

然后!!!最重要的一步,把package.json中的babel配置给删掉,尤其是:react-app!!!

假设我们要使用时间选择器,需要用到模块 DatePicker

import { DatePicker, List } from 'antd-mobile';

<DatePicker

value={this.state.date}

onChange={date => this.setState({ date })}

>

<List.Item arrow="horizontal">Datetime</List.Item>

</DatePicker>

其余的UI组件类似

七、css的模块化

修改配置文件

webpack.config.dev.js

webpack.config.prod.js

组件内部创建style.css

UI组件内部使用

import React, {Component} from 'react';

import style from './style.css';

export default class UI extends Component {

componentDidMount () {

this.props.getBannerList();

this.props.getProList();

}

render () {

console.log('props', this.props)

return (

<div className = "container">

<div className = {style.box}>

<ul>

{

this.props.prolist.map((item,index) => {

return (

<li key = {item.id}>{item.title}</li>

)

})

}

</ul>

</div>

<footer>页面底部</footer>

</div>

)

}

}

转载于:https://blog.51cto.com/7123184/2317144

React全家桶项目搭建相关推荐

  1. 如何实现一个React全家桶项目(附完整教程及代码)

    文章目录 如何实现一个React全家桶项目(附完整教程) 1.相关命令: 运行项目: `yarn start` 项目打包: `yarn build` 暴露配置项: `yarn eject` 2.项目目 ...

  2. React全家桶项目

    开篇 利用业余时间,做了个React项目,算是成品吧,比较简单,还有很多瑕疵.目录结构相当简单.没有数据库,你们运行不起来.想运行起来的话,把express调用数据库的部分全删掉,写死数据. ak47 ...

  3. vue全家桶项目搭建(vue-cli 2.9.6+vue-router+vuex+axios)

    一.安装vue-cli + vue-router + vuex + axios 1.安装vue-cli 2.创建项目 3.安装vuex和axios 二.搭建项目目录结构,如下所示: 1.assets目 ...

  4. React全家桶环境搭建过程

    环境搭建 1.从零开始搭建webpack+react开发环境 2.引入Typescript 安装依赖 npm i -S @types/react @types/react-dom npm i -D t ...

  5. react全家桶从0搭建一个完整的react项目(react-router4、redux、redux-saga)

    react全家桶从0到1(最新) 本文从零开始,逐步讲解如何用react全家桶搭建一个完整的react项目.文中针对react.webpack.babel.react-route.redux.redu ...

  6. 从零搭建React全家桶框架教程

    从零搭建React全家桶框架教程 源码地址:https://github.com/brickspert/react-family 欢迎star 提问反馈:blog 原文地址:https://githu ...

  7. 基于React全家桶开发「网易云音乐PC」项目实战(一)

    网易云音乐PC项目实战 项目简介 1.项目介绍 项目使用到的技术栈 CSS使用Flex进行布局 配置路径别名使用: carco 项目路由使用: react-router来管理 使用react-rout ...

  8. react全家桶从0到1(react-router4、redux、redux-saga)

    本文从零开始,逐步讲解如何用react全家桶搭建一个完整的react项目.文中针对react.webpack.babel.react-route.redux.redux-saga的核心配置会加以讲解, ...

  9. React 全家桶入门教程 01

    React 全家桶入门教程 01 前面是基础课程(难度小,略过),后面是案例 目的 巩固react基础知识,查漏补缺(熟悉的部分快进) 学习相关的库的使用 https://study.163.com/ ...

最新文章

  1. 掩码计算工具netmask
  2. 无声息格式化磁盘的API,VB版
  3. BZOJ2435 [Noi2011]道路修建
  4. container_of宏
  5. python web框架之Tornado
  6. Bailian3142 球弹跳高度的计算【水题】
  7. python和c语言的区别-c语言和python的区别
  8. 超轻量级三级展开列表
  9. Spring框架——day04参数校验和文件上传
  10. weblogic部署模式
  11. bat windows10系统垃圾清理---
  12. 单片机入门学习十五 STM32单片机学习十二 电容触摸按键
  13. 【硬刚大数据】从零到大数据专家之Apache Doris篇
  14. 看视频用这个太爽了!自动实时翻译英语视频
  15. 吞食天地2忘云殇8.77图文攻略
  16. Github新手之路(全过程)(站在前辈的肩膀上的总结)
  17. 谁来PK“百度局域网”
  18. WPS 两个 word 合并
  19. java循环求阶乘_在Java中用循环求阶乘
  20. 微信PC版的缓存文件夹

热门文章

  1. python+selenium爬虫按照名单循环爬取作者知网下载量等信息
  2. 一加6 android p测试,一加6秒速跟进安卓P 教你尝鲜速成开发者
  3. 如何在VC++下动态调整水晶报表图片的大小
  4. 苏宁减持阿里股票获利32亿;京东物流宣称已盈利;三星去年研发投入143亿美元丨价值早报
  5. 创建一个Python脚本,实现以下功能。(1)定义一个元组t1=(1,2,R,py,Matlab‘)和一个空列表1ist1。(2)以while循环的方式,用append()函数依次向listl中
  6. android厨房的使用方法,【图片】【教程】用安卓厨房制作自己的Rom【颓废rom吧】_百度贴吧...
  7. 今天聊聊关于游戏服务器被攻击的一些问题
  8. 补码运算-溢出和自然丢弃
  9. 解决mac版SourceTree卡顿
  10. win10录完指纹要求验证pin,输完pin闪退