實踐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:可輕撩哈哈