创建项目
create-react-app airbnb
配置别名
安装craco插件
npm install @craco/craco@alpha -D
新建craco.config.js并配置
// craco.config.js
const path = require('path')
const resolve = pathname => path.resolve(__dirname,pathname)
module.exports = {
// less
// webpack
webpack:{
alias:{
"@":resolve("src"),
"components":resolve("src/components"),
"utils":resolve("src/utils")
}
}
}
修改package.json文件
// "start": "react-scripts start",
// "build": "react-scripts build",
// "test": "react-scripts test",
// 修改为
"start": "craco start",
"build": "craco build",
"test": "craco test",
那么我们怎么使用呢?
在components文件夹下面创建hello-world.jsx
import React,{memo} from "react";
import HelloWorld from 'components/hello-world'
const App = memo(()=>{
return (
<div>
<HelloWorld></HelloWorld>
</div>
)
})
export default App
在App.js中使用组件
// 我们引入就可以使用
import HelloWorld from 'components/hello-world'
// 渲染
const App = memo(()=>{
return (
<div>
<HelloWorld></HelloWorld>
</div>
)
})
编写目录结构
上图就是我们的目录结构了。
安装craco-less
npm install craco-less@2.1.0-alpha.0
然后修改我们的craco.config.js
// craco.config.js
const path = require('path')
const CracoLessPlugin = require('craco-less');
const resolve = pathname => path.resolve(__dirname,pathname)
module.exports = {
// less
plugins:[
{
plugin:CracoLessPlugin
}
],
// webpack
webpack:{
alias:{
"@":resolve("src"),
"components":resolve("src/components"),
"utils":resolve("src/utils")
}
}
}
如何检测是否生效呢,我们在assets中编写index.less,并且在App.jsx中引入
// index.less
@primayColor:#f00;
body{
color: @primayColor;
}
css样式的重置
安装我们的normalize.css
npm install normalize.css
并且,在App.jsx中导入我们的normalize.css
import "normalize.css";
然后创建我们的reset.less文件
// reset.less
@import "./variables.less";
body,button,dd,dl,dt,from,h1,h2,h3,h4,h5,h6,hr,input,li,ol,p,pre,td,textarea,th,ul{
padding:0;
margin:0;
}
a{
color: @textColor;
text-decoration: none;
}
img{
vertical-align: top;
}
ul,li{
list-style: none;
}
其中,variables.less是我们定义css变量的文件,如下
@textColor:#484848;
@textColorSecondary:#222;
最后,我们在index.less中引入reset.less
@import "./reset.less";
配置Router
npm install react-router-dom
然后在我们的index.js中使用
import React from 'react';
import ReactDOM from 'react-dom/client';
import { HashRouter } from "react-router-dom";
import App from '@/App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<HashRouter>
<App />
</HashRouter>
</React.StrictMode>
);
创建我们的router/index.js
import React from "react";
import { Navigate } from "react-router-dom";
const Home = React.lazy(()=>import("@/views/home"))
const Entire = React.lazy(()=>import("@/views/entire"))
const Detail = React.lazy(()=>import("@/views/detail"))
const routes = [
{
path:"/",
element:<Navigate to="/home" />
},
{
path:"/home",
element:<Home/>
},
{
path:"/entire",
element:<Entire/>
},
{
path:"/detail",
element:<Detail/>
},
]
export default routes
然后,修改我们的view文件夹并编写我们的页面
// home/index.jsx
import React,{memo} from "react";
const Home = memo(()=>{
return (
<div>Home</div>
)
})
export default Home
// detail/index.jsx
import React,{memo} from "react";
const Detail = memo(()=>{
return (
<div>Detail</div>
)
})
export default Detail
// entire/index.jsx
import React,{memo} from "react";
const Entire = memo(()=>{
return (
<div>Entire</div>
)
})
export default Entire
然后,在App.jsx中引入router/index.js
import React,{memo} from "react";
import { useRoutes } from "react-router-dom";
import routes from "./router";
import "normalize.css";
import "./assets/css/index.less";
const App = memo(()=>{
return (
<div>
<div>header</div>
<div>
{useRoutes(routes)}
</div>
<div>footer</div>
</div>
)
})
export default App
这样我们就配置好了,然而使用手动切换路由的时候会出现报错,是因为我们引入组件是异步引入的,所以我们要在index.js中处理,当文件没加载完毕显示loading字符串,如下:
import React,{Suspense} from 'react'; // 使用Suspense来处理异步加载问题
import ReactDOM from 'react-dom/client';
import { HashRouter } from "react-router-dom";
import App from '@/App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
{/* 这里处理问题 */}
<Suspense fallback="loading">
<HashRouter>
<App />
</HashRouter>
</Suspense>
</React.StrictMode>
);
Redux安装
npm install @reduxjs/toolkit react-redux
安装好之后,我们需要创建store中的index.js
import { configureStore } from "@reduxjs/toolkit";
import homeReducer from "./modules/home"; // 这里使用的是toolkit方式
import entireReducer from "./modules/entire" // 这里使用的是原来手动创建方式
const store = configureStore({
reducer:{
home:homeReducer,
entire:entireReducer
}
})
export default store
然后,我们需要在index.js中使用插件
import React,{Suspense} from 'react';
import ReactDOM from 'react-dom/client';
import { HashRouter } from "react-router-dom";
import { Provider } from 'react-redux'; // 使用的react-redux插件
import "normalize.css";
import "./assets/css/index.less";
import App from '@/App';
import store from './store'; // 引入的store
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Suspense fallback="loading">
<Provider store={store}> {/* 这里我们传入store */}
<HashRouter>
<App />
</HashRouter>
</Provider>
</Suspense>
</React.StrictMode>
);
然后新建我们的store/modules/home.js,也就是用toolkit方式创建的store
import { createSlice } from "@reduxjs/toolkit";
const homeSlice = createSlice({
name:"home",
initialState:{
productList:[]
},
reducers:{
}
})
export default homeSlice.reducer
然后我们创建store/modules/entire模块,目录结构如下图
其中,index.js是我们的导出文件,也就是其他文件调用导入入口
import reducer from "./reducer";
export default reducer;
然后,主要文件就是我们的reducer.js文件,内容如下:
const initialState = {
currentPage:3 // 自己填写的假数据
}
function reducer(state = initialState,action){
switch(action.type){
default:
return state
}
}
export default reducer;
由于我们目前没有引入axios,所以没有服务器请求的真实数据,所以其他两个文件constants.js和createActions.js文件暂时没内容,供我们以后编写。那么我们如何查看存在redux中的数据呢,我们需要安装redux-devtools插件,插件我放在文章资料里面了,请自行下载。
接下来,我们安装axios
安装axios
npm install axios
创建service/index.js文件
import hyRequest from "./request"
export default hyRequest
接着我们来编写我们的request模块
// services/request/index.js
import axios from "axios";
import { BASE_URL,TIMEOUT } from "./config";
class HYRequest {
constructor(baseURL,timeout){
this.instance = axios.create({
baseURL,
timeout
})
this.instance.interceptors.response.use((res)=>{
return res.data
},err=>{
return err
})
}
request(config){
return this.instance.request(config)
}
get(config){
return this.request({...config,method:"get"})
}
post(config){
return this.request({...config,method:"post"})
}
}
export default new HYRequest(BASE_URL,TIMEOUT)
// services/request/config.js
export const BASE_URL = "http://codercba.com:1888/airbnb/api"
export const TIMEOUT = 10000
文件结构如下图所示:
配置好了我们的axios,那么如何使用呢,下面就来做一个测试,是否配置成功吧!
修改我们的views/home/index.jsx
import React,{memo,useEffect, useState} from "react";
import hyRequest from "@/services"; // 这里引入我们的请求配置
const Home = memo(()=>{
// 定义状态
const [highScore,setHighScore] = useState({});
// 网络请求的代码
useEffect(()=>{
hyRequest.get({url:"/home/highscore"}).then(res=>{
setHighScore(res)
})
},[])
return (
<div>
<h2>{highScore.title}</h2>
<h4>{highScore.subtitle}</h4>
<ul>
{
highScore.list?.map((item)=>{
return <li key={item.id}>{item.name}</li>
})
}
</ul>
</div>
)
})
export default Home
感谢大家观看,我们下次见
十天看一部剧,还可以吧
@梦不见的梦 行,谢谢提醒,我优化一下
网站的速度有待提升,每次打开都要转半天还进不来呢
@React实战爱彼迎项目(二) - 程序员鸡皮 哪里有问题了,报错了吗?
@Teacher Du 那是怕你们毕不了业,我大学那会儿给小礼品
我们大学那会,献血还给学分~
@ab 我想去学网安,比如网警,但分也贼高😕
@夜 加油,你一样也可以成为程序员的,需要学习资料可以V我
佬发布的好多技术文章似乎我只能评论这篇,真正的程序员!!哇塞 我也想去献血,过两年就成年了可以去献血了