React Hooks 与 Immutable 数据流实战 note05
搭建项目基本骨架【磨刀不误砍柴工】
对应分支 chapter2
![原始仓]https://github.com/sanyuan0704/react-cloud-music/tree/chapter2
基本搭建三步走
- 路由配置和应用部分
- 公共组件开发
- redux的store创建和引入
一、路由创建
路由文件编写
应用结构从路由文件入手,整理思路
应用骨架 顶部固定内容及tab,下面对应不同功能组件
- 安装依赖
npm install react-router react-router-dom react-router-config --save
- 编写路由
//routes/index.js
import React from 'react';
import { Redirect } from "react-router-dom";
import Home from '../application/Home';
import Recommend from '../application/Recommend';
import Singers from '../application/Singers';
import Rank from '../application/Rank';
export default [
{
path: "/",
component: Home,
routes: [
{
path: "/",
exact: true,
render: () => (
<Redirect to={"/recommend"}/>
)
},
{
path: "/recommend",
component: Recommend
},
{
path: "/singers",
component: Singers
},
{
path: "/rank",
component: Rank
}
]
}
]
路由生效,在App根组件中导入路由配置
import React from 'react';
import { GlobalStyle } from './style';
import { renderRoutes } from 'react-router-config';//renderRoutes 读取路由配置转化为 Route 标签
import { IconStyle } from './assets/iconfont/iconfont';
import routes from './routes/index.js';
import { HashRouter } from 'react-router-dom';
function App () {
return (
<HashRouter>
<GlobalStyle></GlobalStyle>
<IconStyle></IconStyle>
{ renderRoutes (routes) }
</HashRouter>
)
}
export default App;
新建组件文件
//src/appliction/Home/index.js
import React from 'react';
function Home (props) {
return (
<div>Home</div>
)
}
export default React.memo (Home);
然后类似的,创建 Recommend、Singers 和 Rank 组件。
启动项目,打开页面,你可以看到 "home" 已经显示到屏幕,但是这还不够,我们需要展示下面的功能组件,但是你在地址后面加上 /recommend,却并没有显示 Recommend 组件相应的内容,因为 renderRoutes 这个方法只渲染一层路由,之前 Home 处于数组第一层,后面的功能组件在第二层,当然不能正常渲染啦。其实要解决这个问题也非常简单,只需在 Home 中再次调用 renderRoutes 即可。
//src/appliction/Home/index.js
import React from 'react';
import { renderRoutes } from "react-router-config";
function Home (props) {
const { route } = props;
return (
{ renderRoutes (route.routes) }
)
}
export default React.memo (Home);
好,现在你可以访问 /recommend 路由,应该可以看到 Recommend 中的内容。同理,现在也可以正常访问其它的路由啦。
二、公共组件开发
全局样式开发
assets/global-style.js
// 扩大可点击区域
const extendClick = () => {
return position: relative; &:before { content: ''; position: absolute; top: -10px; bottom: -10px; left: -10px; right: -10px; };
}
// 一行文字溢出部分用... 代替
const noWrap = () => {
return text-overflow: ellipsis; overflow: hidden; white-space: nowrap;
}
export default {
'theme-color': '#d44439',
'theme-color-shadow': 'rgba (212, 68, 57, .5)',
'font-color-light': '#f1f1f1',
'font-color-desc': '#2E3030',
'font-color-desc-v2': '#bba8a8',// 略淡
'font-size-ss': '10px',
'font-size-s': '12px',
'font-size-m': '14px',
'font-size-l': '16px',
'font-size-ll': '18px',
"border-color": '#e4e4e4',
'background-color': '#f2f3f4',
'background-color-shadow': 'rgba (0, 0, 0, 0.3)',
'highlight-background-color': '#fff',
extendClick,
noWrap
}
顶部栏开发
- home/目录下创建 style.js 创建样式
import styled from'styled-components';
import style from '../../assets/global-style';
export const Top = styled.divdisplay: flex; flex-direction: row; justify-content: space-between; padding: 5px 10px; background: ${style ["theme-color"]}; &>span { line-height: 40px; color: #f1f1f1; font-size: 20px; &.iconfont { font-size: 25px; } }
很简单的布局和样式,就不过多解释了。接下来在 Home 组件应用这些样式,
//src/appliction/Home/index.js
import React from 'react';
import { renderRoutes } from "react-router-config";
import { Top } from './style';
function Home (props) {
const { route } = props;
return (
<div>
<Top>
<span className="iconfont menu"></span>
<span className="title">WebApp</span>
<span className="iconfont search"></span>
</Top>
{ renderRoutes (route.routes) }
</div>
)
}
export default React.memo (Home);
接着来编写上面的 tab 栏,先定义样式:
export const Tab = styled.div`
height: 44px;
display: flex;
flex-direction: row;
justify-content: space-around;
background: ${style ["theme-color"]};
a {
flex: 1;
padding: 2px 0;
font-size: 14px;
color: #e4e4e4;
&.selected {
span {
padding: 3px 0;
font-weight: 700;
color: #f1f1f1;
border-bottom: 2px solid #f1f1f1;
}
}
}
`
export const TabItem = styled.div`
height: 100%;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
在 Home 组件中使用:
import React from 'react';
import { renderRoutes } from "react-router-config";
import {
Top,
Tab,
TabItem,
} from './style';
import { NavLink } from 'react-router-dom';// 利用 NavLink 组件进行路由跳转
function Home (props){
const { route } = props;
return (
<div>
<Top>
<span className="iconfont menu"></span>
<span className="title">Web App</span>
<span className="iconfont search"></span>
</Top>
<Tab>
<NavLink to="/recommend" activeClassName="selected"><TabItem><span > 推荐 </span></TabItem></NavLink>
<NavLink to="/singers" activeClassName="selected"><TabItem><span > 歌手 </span></TabItem></NavLink>
<NavLink to="/rank" activeClassName="selected"><TabItem><span > 排行榜 </span></TabItem></NavLink>
</Tab>
{ renderRoutes (route.routes) }
</div>
);
}
export default React.memo (Home);
打开页面,现在一个像样的 WebApp 头部就出来了,并且点击不同的 tab
三、redux准备
成熟的状态管理库 实现单一数据源
依赖安装
npm install redux redux-thunk redux-immutable react-redux immutable --save
创建store
store文件夹下创建index.js reducer.js