1. 程式人生 > >實踐webpack+es6+react+redux+antd構建專案(二) react,redux,antd引入

實踐webpack+es6+react+redux+antd構建專案(二) react,redux,antd引入

上一篇文章是關於從零構建一個webpack專案,基本已經啟動成功了,這篇文章將會講一下在專案中使用目前最流行的React框架

1、引入babel相關

現代前端基本都是以es6為規範進行開發,所以我們專案中也就需要引入es6。es6是需要使用babel進行轉換的,瀏覽器才能識別

npm install --save-dev babel-core babel-loader babel-preset-env babel-preset-es2015 babel-preset-stage-0
npm i --save-dev babel-plugin-import babel-plugin-transform-decorators-legacy babel-plugin-transform-runtime
npm i --save-dev babel-preset-react babel-preset-react-app

 這是專案中關於解析es6的babel引入。安裝依賴之後,進行配置

在根目錄新建一個  .babelrc 用於babel的配置

 
{
    "presets": ["es2015", "env", "react", "stage-0"],
    "plugins": [
        [
            "import", {
                "libraryName": "antd",
                "libraryDirectory": "es",
                "style": "css"
            }
        ],
        [
            "transform-runtime",
            {
              "helpers": false,
              "polyfill": false,
              "regenerator": true,
              "moduleName": "babel-runtime"
            }
        ],
        ["transform-decorators-legacy"]
    ]
}

2、引入react,redux

npm i --save-dev react react-dom redux react-redux react-router-dom redux-thunk

對於版本方面我們沒有特別的要求,所以就直接是最新版的。

3、引入antd

npm i --save-dev antd

4、新增檔案

建立這樣的專案結構, 我們依次新增內容。

首先你需要對react,redux有基本的瞭解,如果沒有,建議去學習一下,如果直接構建專案但是又不瞭解基礎知識,其實是學不到什麼的。

index.js

import React from 'react';
import ReactDom from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import history from './utils/history';
import storeTree from './store';
import App from './APP';

const store = createStore(storeTree, applyMiddleware(thunk));

ReactDom.render(
    <Provider store={store}>
        <App history={history}/>
    </Provider>,
    document.getElementById('app')
)

APP.js

import React from 'react';
// import { Router, Route, Switch } from 'react-router-dom';
import {
    BrowserRouter as Router,
    Route,Switch
  } from 'react-router-dom';
import PropTypes from 'prop-types';
import TodoList from './pages/todoList';
import TodoDetail from './pages/todoDetail';

const App = ((history) => {
    return (    
        <Router history={history}>
            <Switch>
                <Route path="/" exact component={TodoList}></Route>
                <Route path="/todoList" exact component={TodoList}></Route>
                <Route path="/todoDetail" exact component={TodoDetail}></Route>
            </Switch>
        </Router>
    )
});
App.propTypes = {
    history: PropTypes.shape({}).isRequired
};
export default App;

store.js

import { combineReducers } from 'redux';
import todoListReducer from './pages/todoList/reducer';
import todoDetailReducer from './pages/todoDetail/reducer';

const storeTree = combineReducers({
    todoListReducer,
    todoDetailReducer
});

export default storeTree;

utils/history.js

// import createHistory from 'history/createBrowserHistory';
import { createBrowserHistory as createHistory } from 'history';

export default createHistory();

utils/request.js

export default async function request(url, options) {
    return requestDataProcess(url, options);
}
async function requestDataProcess(url, options) {
    if (/post/i.test(options.method)) {
        let { data } = options;
        let body = null;
        if (typeof data === 'string') {
            body = data;
        } else {
            body = JSON.stringify(data);
        }
        options.body = body;
        delete options.data;
    }
    let headers = {};
    headers['Content-Type'] = 'application/json';
    options.headers = headers;

    const result = await fetch(url, options).then(res => res.json());
    return result;
}

pages/todoList/index.js

import React, { PureComponent } from 'react';
import { Table, Button } from 'antd';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { getTodoList } from './action';

@connect(
    state => state,
    {
        getTodoList
    }
)

class TodoList extends PureComponent {
    static propTypes = {
        getTodoList: PropTypes.func.isRequired,
        todoListReducer: PropTypes.shape({
            listData: PropTypes.array.isRequired
        }).isRequired
    };
    constructor(props){
        super(props);
    }
    componentDidMount(){
        this.props.getTodoList();
    }
    render() {
        const columns = [
            {title:'事件',dataIndex:'item'},
            {title:'原因',dataIndex:'reson'},
            {title:'解決辦法',dataIndex:'function'},
            {title:'結果',dataIndex:'result'}
        ]
        const data = this.props.todoListReducer.listData;
        return (
            <div>
                <Table
                    rowKey={(record)=>record.id}
                    columns={columns}
                    dataSource={data}
                />
                <Button onClick={()=> {this.props.history.push('./todoDetail')}}>跳轉詳情</Button>
            </div>
        )
    }
}

export default TodoList;

pages/todoList/action.js

import request from '../../utils/request';

const listData = res => ({
    type: 'LIST_DATA',
    payload: res
});

export const getTodoList = (params, fn) => async (dispatch) => {
    try {
        const result = await request('/api/qq/changeData', {
            method: 'POST',
            data: params
        });
        await dispatch(listData(result.data));
        fn();
    } catch (error) {

    }
}

pages/todoList/reducer.js

const initState = {
    listData: [
        {id:1, item: 'sss', reson: 'sad', function: 'asdsd', result: 'ewwwqw'},
        {id:2, item: 'sss', reson: 'sad', function: 'asdsd', result: 'ewwwqw'},
        {id:3, item: 'sss', reson: 'sad', function: 'asdsd', result: 'ewwwqw'},
        {id:4, item: 'sss', reson: 'sad', function: 'asdsd', result: 'ewwwqw'}
    ]
};

const todoListReducer = (state=initState, action) => {
    switch (action.type) {
        case 'LIST_DATA':
            return {
                ...state,
                ...action.payload,
                listData: action.payload
            };
        default: 
            return {
                ...state
            };
    }
}

export default todoListReducer;

pages/todoDetail/index.js

import React, { PureComponent } from 'react';
import { Card, Button } from 'antd';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { getTodoDetail } from './action';
import './index.less';

@connect(
    state => state,{
        getTodoDetail
    }
)

class TodoDetail extends PureComponent {
    static propTypes = {
        getTodoDetail: PropTypes.func.isRequired,
        todoDetailReducer: PropTypes.shape({
            info: PropTypes.objectOf.isRequired
        }).isRequired
    };
    constructor(props){
        super(props)
    }
    componentDidMount(){
        this.props.getTodoDetail();
    }
    render() {
        const { info } = this.props.todoDetailReducer;
        return (
            <div>
                <Card>
                    {info.asd}
                </Card>
                <Card className="st">我來顯示個數據</Card>
                <Button onClick={()=> {this.props.history.push('./todoList')}}>那我跳回列表</Button>
            </div>
        )
    }
}

export default TodoDetail;

pages/todoDetail/action.js

import request from '../../utils/request';

const detailData = res => ({
    type: 'DETAIL_DATA',
    payload: res
});

export const getTodoDetail = (params, fn) => async (dispatch) => {
    try {
        const result = await request('/api/qq/changeData', {
            method: 'POST',
            data: params
        });
        await dispatch(detailData(result.data));
        fn();
    } catch (error) {
        
    }
}

pages/todoDeatil/reducer.js

const initState = {
    info: {
        asd:'232323123213'
    }
};

const todoDetailReducer = (state=initState, action) => {
    switch (action.type) {
        case 'DETAIL_DATA':
            return {
                ...state,
                ...action.payload,
                info: action.payload
            };
        default: 
            return {
                ...state
            };
    }
}

export default todoDetailReducer;

5、問題

在引入的過程中很多問題,大多都是babel配置的問題,因為babel7.x版本升級的原因,所以大部分都是在處理這個問題。

dist/index.html中 加入

<div id="app"></div>

Plugin/Preset files are not allowed to export objects,webpack報錯/babel報錯的解決方法 

最終呈現的頁面就是

將會把這個專案上傳到github上,需要的同學可以自行下載執行。

目前來說實現了一個基本的react專案,之後會更加完善這個專案,也會持續更新,做一個比較完善的中後臺系統。

連結:實踐webpack+es6+react+redux+antd構建專案(一) webpack配置

關注我獲取更多前端資源和經驗分享

關注後回覆    vivi     獲取我的微訊號,望不吝賜教,pps:可輕撩哈哈