实践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上,需要的同学可以自行下载运行。