??斗地主捕鱼电竞提现秒到 广告位招租 - 15元/月全站展示
??支付宝搜索579087183领大额红包 ??伍彩集团官网直营彩票
??好待遇→招代理 ??伍彩集团官网直营彩票
??络茄网 广告位招租 - 15元/月全站展示
React全家桶项目搭建

转载   吴勋勋007   2018-11-15   浏览量:23


资源: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???br/>

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???br/>

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组件内部需要在组件装载完毕之后请求数据,又不希望在容器组件内部请求数据,需要用到异步请求??閞edux-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('//www.daxunxun.com/douban').then(data => {

      dispatch({

        type: 'CHANGE_BANNER',

        data

      })

    })

  },

  getprolist (dispatch) {

    getData('//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

五、设置路由???/span>

1、安装路由???br/>

cnpm i react-router-dom -S

2、创建路由??閞outer/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的??榛?/span>

修改配置文件

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>

    )

  }

}


转载自://blog.51cto.com/7123184/2317144

招聘 不方便扫码就复制添加关注:程序员招聘谷,微信号:jobs1024



解决vue项目中type=”file“ change事件只执行一次的问题
这篇文章主要介绍了vue项目中解决type=”file“change事件只执行一次的问题,本文给大家介绍的非常详细,需要的朋友可以参考下
react中使用swiper的具体方法
本篇文章主要介绍了react中使用swiper的具体方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
使用webpack搭建react开发环境的方法
本篇文章主要介绍了使用webpack搭建react开发环境的方法,在这篇文章中我们开始利用我们之前所学搭建一个简易的React开发环境,用以巩固我们之前学习的Webpack知识。一起跟随小编过来看看吧
NodeJs搭建本地服务器之使用手机访问的实例讲解
今天小编就为大家分享一篇NodeJs搭建本地服务器之使用手机访问的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
详解各版本React路由的跳转的方法
这篇文章主要介绍了详解各版本React路由的跳转的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
React从react-router路由上做登陆验证控制的方法
本篇文章主要介绍了React从react-router路由上做登陆验证控制的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
React调试错误'Module not found: Can't resolve'
React调试错误'Modulenotfound:Can'tresolve'
Flaapy Bird项目笔记
最近做了个像素鸟小游戏,整理下笔记心得:不管页面上有多少个演员,只有一个定时器,这个定时器的业务超级简单:setInterval(function(){//让所有演员更新//让所有演员渲染},20)1.所有的演员都必须提供update()render()方法,这实际上叫做面向接口编程。Java中,“类”是一种比较抽象的概念,比"类"还抽象一层的东西叫做接口,就是制定必须有哪些方
React Navigation 使用中遇到的问题小结
本篇文章主要介绍了ReactNavigation使用中遇到的问题小结,主要是安卓和iOS中相对不协调的地方,特此记录,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
详解React-Router中Url参数改变页面不刷新的解决办法
这篇文章主要介绍了详解React-Router中Url参数改变页面不刷新的解决办法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧