着手与react-app的学习

一直在使用vue,react快忘记了故,重新学习react项目全方位的搭建

  1. 安装react脚手架

    npm i create-react-app  -g  //脚手架可以简化复杂的配置
    
  2. 创建项目

    create-react-app react-demo
    
  3. 脚手架中安装react-router,react-router-dom

    npm i React-Router React-Router-DOM --save
    

    1)、React-Router-DOM:提供了 BrowserRouter, Route, Link等 API,我们可以通过 DOM 的事件控制路由。例如点击一个按钮进行跳转,大多数情况下我们是这种情况,所以在开发过程中,我们更多是使用React-Router-DOM。
    2)、React-Router:提供了一些router的核心API,包括Router, Route, Switch等,但是它没有提供 DOM 操作进行跳转的API。
    现在的项目结构应该是这样的

react-demo/
  README.md
  node_modules/
  package.json
  public/
    index.html
    favicon.ico
  src/
    App.css
    App.js
    App.test.js
    index.css
    index.js
    logo.svg

暂时不考虑webpack的配置问题

src中index.js 相当于vue的main.js 它理应是这样的结构

	import React from 'react';
	import ReactDOM from 'react-dom';
	import './index.css';
	import App from './App';
	import * as serviceWorker from './serviceWorker';
	
	ReactDOM.render(<App />, document.getElementById('root'));
	
	serviceWorker.unregister();

运用 npm run start 运行一下是否正常

下一步思考:路由如何跳转
在看了react-router与react-router-dom的区别之后,发现两者不可或缺,都安装下来,前文有安装代码
进一步思考:为了方便管理,路由是否可单独写个js,然后导入index.js
答:可以,在此看到了react的特别代码格式jsx
执行:

  1. 在src中建立文件夹routes并在其中建立index.jsx文件。
    index.jsx内容(因为本身不熟悉react,但是接触过router类组件,对此代码可以很好的理解)

    import React from 'react'
    import { Route,Redirect } from 'react-router'
    import { HashRouter,Switch } from 'react-router-dom'
    
    import Home from '../App'
    import Cs1 from '../pages/cs1.jsx'
    
    const Routes = () => (
      <HashRouter>
        <div>
          <Route exact path="/" render={()=><Redirect to="/home" />}></Route> //默认进入页面 
          <Switch> //声明
            <Route path="/home" component={Home} />
            <Route path="/cs1" component={Cs1} />
          </Switch>
        </div>
      </HashRouter>
    )
    
    const App = () => (
      <Routes />
    )
    
    export default App
    
  2. 改变src下的index.js

    //将App 的路径改为./routes/index 就成功的吧路由引入了,理所应当但又感觉到了神奇
    import App from './App';
    import App from './routes/index';
    
  3. 思考:既然路由配置成功了,那跳转试试?
    在‘/’路径页面(这里是App.js是的不是什么html,vue)

    import React from 'react'
    import { Link } from 'react-router-dom'
    import logo from './logo.svg'
    import './App.css'
    
    function App() {
      return (
        <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <h1>首页</h1>
            <Link to="/cs1">测试1</Link>
          </header>
        </div>
      );
    }
    
    export default App;
    

    在src中新建文件夹pages并在期间创建cs1.jsx 文件为测试页面
    cs1.jsx文件内容

    import React from 'react'
    import { Link } from 'react-router-dom'
    
    const cs1 = () => (
      <div>
        <h1>这是测试1页面</h1>
        <Link to="/home">返回首页</Link>
      </div>
    )
    
    export default cs1
    

    保存后运行代码实现了基本的页面跳转功能,但是离完成一个完整的项目来说,只是冰山一角(学习到此记录20190819上午记录)
    开始学习:
    思考:一个项目最开始执行的一定是判断用户是否登录,猜测所用到的东西,store(新名词,redux, react-redux)
    答:经过整一天的查阅学习,才稍微搞懂了router-redux与redux的用法与原理(待后期深入学习)

    首先将用到的包安装下来

    npm install redux react-redux --S
    

    开始redux的部分
    新建文件reducer.js

    // 引入redux
    import { combineReducers } from 'redux'
    // 保存的值
    const defaultState = {
      inputValue: '123',
      list: [1,2]
    }
    
    const dedState = {list:2}
    // 用于后面修改保存值 按需求写
    function reducer(state = defaultState, action) {
      if( action.type === 'change_input_value') {
        const newState = JSON.parse(JSON.stringify(state))
        newState.inputValue = action.value
        return newState
      }
      return state
    }
    
    function ress(state = dedState, action) {
      if (action.type === 'add_todo_item') {
        return Object.assign({}, state, {
          list: action.value
        })
      }
      return state
    }
    // 抛出定义的函数
    export default combineReducers({reducer,ress})
    

    在reducer.js同级目录下新建index.js

    import { createStore, applyMiddleware, compose } from 'redux'
    import reducers from './reducer'
    // 创建store
    const store = createStore(reducers)
    
    export default store
    

    开始redux的部分
    在最开始的src/index.js下修改部分代码

    import { Provider } from 'react-redux'
    import store from './store/index'
    // 运用react-redux将store带入每个路由组件中
    ReactDOM.render((
      <Provider store={store}>
        <BrowserRouter>
            <App />
        </BrowserRouter>
      </Provider>
    ), document.getElementById('root'));
    

    选定一个组件用于取改值,这里取App.js 这里的App 并不是上图的 App /> 不清楚请查看路由配置部分

    class App extends React.Component {
      constructor(props) {
        super(props)
        this.state = {
          demo: this.props.demo // 获取store中值
        }
        this.handleClick = this.handleClick.bind(this)
      }
      handleClick(e, name) {
        e.preventDefault();
        const action = {
          type: 'add_todo_item',
          value: 5
        }
        // 更改store中数据
        this.props.ress(action)
      }
      render() {
        return (
          <div className="App">
            <header className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <h1 onClick={(e) => this.handleClick(e,this.state.demo)}>{this.props.demo.list}</h1>
              <Link to="/cs1">测试1</Link>
              <Cs />
            </header>
          </div>
        )
      }
    }
    // 将store内值带入props
    const mapStateToProps = (state, ownProps) => {
      return {
        demo: state.ress
      }
    }
    // 将redux的 dispatch 带入props并变更名为ress
    const mapDispatchToProps = (dispatch, ownProps) => {
      return {
        ress: (val) => dispatch({type: val.type,value: val.value})
      }
    }
    // 重要!必须connect之后store中的数据才能插入到props中
    const app = connect(mapStateToProps, mapDispatchToProps)(App);
    
    export default app;
    

    到此,已经了解了react的路由跳转,store的数据管理,下一步应该做的就是ajax数据的获取了,相信他会比前两个轻松的多(20190820下午留)

    数据交互我这里用到的是axios qs包

		npm install axios
		npm install qs
	在/src下创建新文件夹util与api
	
	util里创建request.js
	这一部分代码习惯性原因,我直接拿了vue-elementui-admin里的axios用法,比较符合我的需求
		import axios from 'axios' // 引入axios
		// 创建一个axios实例
		const service = axios.create({
		 baseURL: 'http://v.16mnc.cn:8083/neighbour_goods_admin', // url = base url + request url
		 headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
		 withCredentials: true, // 当跨域请求时发送cookie
		 timeout: 25000 // 请求时间限制ms
		})
		// 请求拦截器
		service.interceptors.request.use(
		 config => {
		   // 在发送请求之前做些什么
		
		   if (store.getters.token) {
		     // 让每个请求携带令牌
		     // ['X-Token'] 是一个自定义头键
		     // 请根据实际情况修改
		     // config.headers['X-Token'] = getToken()
		   }
		   return config
		 },
		 error => {
		   // 处理请求错误
		   console.log(error) // for debug
		   return Promise.reject(error)
		 }
		)
		// 响应拦截器
		service.interceptors.response.use(
		 /**
		  * 如果您想获得http信息,例如头信息或状态信息
		  * 请 return  response => response
		 */
		
		 /**
		  * 通过自定义代码确定请求状态
		  * 这里只是一个例子
		  * 您还可以通过HTTP状态代码来判断状态
		  */
		 response => {
		   const res = response.data
		   // if the custom code is not 20000, it is judged as an error.
		   if (res.status !== 200) {
		     Message({
		       message: res.msg || 'Error',
		       type: 'error',
		       duration: 5 * 1000
		     })
		
		     // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
		     if (res.status === 50008 || res.status === 50012 || res.status === 50014) {
		       // to re-login
		       MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
		         confirmButtonText: 'Re-Login',
		         cancelButtonText: 'Cancel',
		         type: 'warning'
		       }).then(() => {
		         store.dispatch('user/resetToken').then(() => {
		           location.reload()
		         })
		       })
		     }
		     return Promise.reject(new Error(res.msg || 'Error'))
		   } else {
		     return res
		   }
		 },
		 error => {
		   console.log('err' + error) // for debug
		   Message({
		     message: error.msg,
		     type: 'error',
		     duration: 5 * 1000
		   })
		   return Promise.reject(error)
		 }
		)
		export default service
		```
		
		/api下创建user.js
		
		```
		import request from '../utils/request'
		import qs from 'qs'
		
		export function login(data) {
		 return request({
		   url: '/login/login',
		   method: 'post',
		   data: qs.stringify({
		     adUsername: data.username,
		     adPassword: data.password
		   })
		 })
		}
		```
		在其他页面调用的时候
		
		```html
		import { login } from './api/user'
		
		handleClick(e, name) {
		 e.preventDefault();
		 login({name: 123456,password: 123456})
		 .then(res => {
		  console.log(res)
		  const action = {
		    type: 'change_input_value',
		    value: {
		      name: res.data.name,
		      password: res.data.password
		    }
		  }
		     this.props.ress(action)
		 })
		 .catch(error =>{
		   console.log(error)
		 })
		}

到这里react项目前期工作准备已经完成,有错误的地方希望大家给予指正,我也是才学习react的小歘歘O(∩_∩)O~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值