使用React构建精简版本掘金(一)

5次阅读

共计 3668 个字符,预计需要花费 10 分钟才能阅读完成。

最近正在学习 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 文件如下
在根目录中创建 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 中文文档
到目前为止,基础结构就算是完成了,后续的就需要往各个页面添加实际内容了。

目前效果图如上所示,后续不断更新中。以上详细代码见 github, 欢迎点赞,您的点赞是我的动力。

正文完
 0