react 專案全家桶構件流程
阿新 • • 發佈:2018-11-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模組
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模組
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元件內部需要在元件裝載完畢之後請求資料,又不希望在容器元件內部請求資料,需要用到非同步請求模組redux-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('
http://www.daxunxun.com/douban').then(data => {
&nb