使用React構建精簡版本掘金(一)

abcjob發表於2021-09-09

最近正在學習react,就想著能不能用react做一個專案,平時瀏覽掘金,就拿掘金練手吧!

使用React構建精簡版本掘金(一)
是不是可以以假亂真呢!???

初始化

  • 使用create-react-app初始化專案結構
yarn create react-app react-juejin
複製程式碼

這個腳手架會自動幫助我們搭建基礎工程,同時安裝React專案的各種必要依賴,如果在過程中出現網路問題,請嘗試配置代理或使用其他 npm registry。
進入專案並啟動

cd react-juejin
yarn start
複製程式碼
  • 安裝ant-design
yarn add antd
複製程式碼
  • 配置UI庫懶載入樣式
    需要對整個專案重新配置,這裡使用了react-app-rewired (一個對 create-react-app 進行自定義配置的社群解決方案)。
yarn add react-app-rewired customize-cra
複製程式碼

修改package.json 檔案如下

使用React構建精簡版本掘金(一)
在根目錄中建立config-overrides.js,用於重寫覆蓋預設的配置

module.exports = function override(config, env) {
  // do stuff with the webpack config...
  return config;
};
複製程式碼
  • 使用 babel-plugin-import 該外掛用於按需載入plugins和樣式
yarn add babel-plugin-import
複製程式碼

修改上步建立的config-overrides.js

const { override, fixBabelImports } = require('customize-cra');

module.exports = override(
    fixBabelImports('import', {
        libraryName: 'antd',
        libraryDirectory: 'es',
        style: 'css',
    })
);
複製程式碼
  • 新增less-loader
    個人習慣使用less,看個人喜好安裝即可,不過查閱上面社群方案react-app-rewired,並沒有提供比如sass的重寫方案,故如果需要使用sass,可採用別的方案引入。
yarn add less less-loader
複製程式碼

修改config-overrides.js

//const { override, fixBabelImports } = require('customize-cra');
const { override, fixBabelImports, addLessLoader } = require('customize-cra');

module.exports = override(
    fixBabelImports('import', {
        libraryName: 'antd',
        libraryDirectory: 'es',
        style: true,
    }),
    addLessLoader({
        javascriptEnabled: true,
    }),
);
複製程式碼

以上詳細配置的話可參考ant-design官網

引入redux

  • 安裝
yarn add redux react-redux --save
複製程式碼
  • 使用方式 考慮到之後可能會有多個reducer,開始就把結構弄好,做成日後可以方便合併使用多個reducer的方式
    (1)建立一個reducer
// 建議使用這中結構

// 1.定義預設資料
let initialState = {
    notificationCount: 0
}

// 2.Reducer
const pageHeaderReducer = (state = initialState, action) => {
    switch (action.type) {
        case 'CHANGE_COUNT':
            return { ...state, notificationCount: action.notificationCount }
        default:
            return state
    }
}
// 3.匯出
export default pageHeaderReducer;
複製程式碼

(2)建立index.js,作為合併所有reducer的檔案。

import {combineReducers} from 'redux';

import pageHeaderReducer from './pageHeader.js';

const appReducer = combineReducers({
    pageHeaderReducer
});
export default appReducer;
複製程式碼

(3)App.js中使用定義好的reducer

import { createStore } from 'redux'
import { Provider } from 'react-redux'
import appReducer from './reducers/index.js';
// 使用合併後的那個Reducer
const store = createStore(appReducer);
class App extends Component {
  constructor(props){
    super(props);
  }
  ...
  render() {
    return (
      <Provider store={store}>
        <div className="App">
          ...
        </div>
      </Provider>
    );
  }
}
複製程式碼

(4)在header/index.js中使用redux

import { connect } from 'react-redux';

class Header extends Component {
    ...
    render() {
        ...
        return (
            <Affix offsetTop={this.state.top}>
                ...
                <Badge count={this.props.count} overflowCount={10}>
                    <a href="/">
                        <Icon type="notification" />
                    </a>
                </Badge>
            </Affix>
        );
    }
}

const mapStateToProps = (state) => {
    return {
        count: state.pageHeaderReducer.notificationCount
    }
}

Header=connect(mapStateToProps)(Header)

export default Header;
複製程式碼

到目前為止,就可以在外部修改notificationCount的值,通過redux,元件內部就可以正常獲取到對應的count值。
更詳細的redux配置可以參考redux中文文件

新增路由react-router

首頁導航中存在5個tab切換,分別對應這不同的頁面內容。接下來介紹如何通過react-router實現不同頁面內容的跳轉。

  • 安裝react-router
yarn add react-router-dom --save
複製程式碼
  • 使用方式
import { Switch, Route } from 'react-router-dom';
...
class Main extends Component {
    constructor(props) {
        super(props);
        this.state = {  }
    }
    render() {
        return (
            <div>
                <Switch>
                    <Route exact path='/' component={Home}/>
                    <Route path='/timeline' component={Home}/>
                    <Route path='/dynamic' component={Dynamic}/>
                    <Route path='/topic' component={Topic}/>
                    <Route path='/brochure' component={Brochure}/>
                    <Route path='/activity' component={Activity}/>
                </Switch>
            </div>
        );
    }
}
複製程式碼

上面的exact表示絕對匹配/,如果不註明exact,則/還會匹配/timeline等等上面程式碼實現了一個類似tabbar切換的效果

  • tab導航
render() {
        return (
            <ul>
                {this.state.navs.map((item,index)=>{
                    return <li key={item.path} className={item.isActived?'activeLi':''} onClick={this.handelClick.bind(this,index)}>
                                <Link to={item.path}>{item.text}</Link>
                            </li>
                })}
            </ul>
        );
    }
複製程式碼

react-router中提供了Link和NavLik兩種方式,如果僅僅需要匹配路由,使用Link就可以了,而NavLink的不同在於可以給當前選中的路由新增樣式, 比如上面寫到的activeStyle和activeClassName
更詳細的react-router配置可以參考React-router中文文件

到目前為止,基礎結構就算是完成了,後續的就需要往各個頁面新增實際內容了。

使用React構建精簡版本掘金(一)

目前效果圖如上所示,後續不斷更新中。以上詳細程式碼見github,歡迎點贊,您的點贊是我的動力。

相關文章