I. Introducción
Este proyecto es para
react新手入门
una demostración de星巴克
componentes de imitación. Si puede ayudarlo, proporcione uno pequeño点赞
. En segundo lugar, este proyecto utiliza el código del神三元
tipo grande en elreact-cloud-music
proyecto de código abierto: código fuente de react-cloud-music , react-cloud -folleto de música para explicar .工具组件
Voy a explicar algunos de ellos utilizados .
1.0, tonterías
- Principalmente quiero integrar algunos conocimientos en mi propio proyecto (comprensión) en la forma de aprender el proyecto del jefe. Tiene
网络请求
una actualización relativamente grande desde el primer episodio del proyecto. Las otras páginas originales solo se actualizan conredux
datos. gestión de flujo. Si está interesado, puede收藏
o关注专栏
1.1 Visualización del proyecto y dirección del proyecto
- En cuanto al estilo, con el fin de ponerse al día con el trabajo, no se ha hecho bien
rem适配
. Después de que se publique el artículo, se acelerará la修改
adaptación . - Si es posible, asigne una estrella al soporte: código fuente del proyecto github
- Si es posible, dé una estrella para respaldarlo: código fuente del proyecto gitee
1.2 Contenido de esta actualización
- Hacer la encapsulación de la solicitud de red.
api/config
- Estabilización de imagen de plato de búsqueda (
debounce
) - Carga diferida de la página del menú (
lazy-load
) - Actualice
redux
DFM (no me pregunte por qué lo sigo usandoredux
) - Lista de búsquedas populares durante la búsqueda (
hotlist
) - Implementación del carrusel de la página de inicio (
swiper
)
2. Reducción
2.0, diseño técnico
- Esta actualización
redux
no ha cambiado más que las cosas nuevas. - 相较于第一集,
网络请求
方面有较大的变化
2.1、理解redux(从useState过渡)
- 首先我不得不说,这个项目的
数据量
根本不至于用到redux,但是为了更好的理解redux
,我还是把他加到了这个项目当中,那么我们要如何从原来
在页面中通过useState()
定义数据的初始状态,以及改变的setXXX()
函数,到现在
的redux数据流管理? - 从页面的
useState
的思想中跳出来,当我们开发一个大型项目
的时候,不可能把数据放在当前要运行
的页面,这样不利于协同开发
,页面多了数据也无法管理
,所以我们用一个公共的数据仓库
存一下页面所涉及的数据 - 当前页面要发生
状态变化
的时候,当前页面
打一个电话给store
,store
收到了要变化的条件
,返回给页面对应的状态
,从而实现MVVM
(具体实现中间还有很多过程,为了便于理解这么讲)。
- Store:Store 就是保存数据的地方,你可以把它看成一个容器。
- State:Store对象包含所有数据。如果在某个页面数据,就要对 Store 生成快照。
- Action:在原来的useState中,State 的变化,会导致 View 的变化。但是,用户接触不到 State,只能接触到 View。所以,State 的变化必须是 View 导致的。Action 就是 View 发出的通知,表示 State 应该要发生变化了。
- ActionCreators:指明Action变化的种类
- dispatch():是 View 发出 Action 的唯一方法。
- Reducer:Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State。
三、项目实现
3.0、封装网络请求
- 上次我们把
数据过滤
放在数据请求
里,这样请求一多,request
文件会变得很复杂 - 为了在代码上线时候可以快速修改
localhost:3000
为服务器端url
我们进行了一层封装,实现request.config
{/*代码实现*/} // 配置请求对象 import axios from 'axios' // 本地调试 dev 开发阶段,baseurl为远程基础url export const baseUrl = "https://www.fastmock.site/mock/5321bf649d06645c4266f3e0d45ae1cc"; const axiosInstance = axios.create({ baseURL: baseUrl }) axiosInstance.interceptors.response.use( res => res.data, err => { console.log(err, '网络错误~~') } ) export { axiosInstance }
{/*代码实现*/} import axios from 'axios' import { axiosInstance } from "./config"; export const getMenuListRequest = () => axiosInstance.get('/menu/all') export const getHotListRequest = () => axiosInstance.get('/menu/hot')
3.1、实现搜索+防抖+useMemo
- 这里把搜索懒加载放到
0.8s
实现搜索一次,效果明显一点,如果是自己写项目,0.3
左右即可,太长用户体验不好 - 搜索防抖的实现
工具类
随处可见,如果想自己实现的话可以参考下面的代码,甚至可以直接用lodash
中的`debounce - 搜索实现
- 这里我仿造
神三元
大佬在其项目中的搜索,最外层用了一个Search组件
,内层用SearchBox
包了一层 Search
组件有一个query变量(便于理解我们叫他fatherQuery
),和一个handleQuery函数
用于修改fatherQuery
SearchBox
组件有自己的query(便于理解我们叫他sonQuery
),同时接收传进来的Search
中的fatherQuery
和handleQuery
- 在
SearchBox
中修改的sonQuery
,进行防抖处理,每隔800
毫秒,执行一次handleQuery
去修改Search
中的fatherQuery
,因为最后是fatherQuery
执行dispatch
改变状态
//父组件Search function Search(props) { const {hotList,suggestList} = props; const {getHotKeyMenuDispatch,getSuggestMenuDispatch} = props //这个useEffect只有每隔800ms才会得到重新渲染的机会 useEffect(()=>{ getSuggestMenuDispatch(query); },[query]) //用于在子组件searchBox执行,更新父组件的query //但是子组件有防抖,需要每隔800ms执行一次 const handleQuery = (q) =>{ setQuery(q) } return( <> <SearchBox newQuery={query} handleQuery={handleQuery}> </SearchBox> </> ) }
export default memo(function SearchBox(props) { //得到父组件的变量与函数 const {handleQuery} = props const [query,setQuery] = useState('') useEffect(() => { //父组件的query去dispatch更新状态 handleQueryDebounce(query) }, [query]) //防抖 let handleQueryDebounce = useMemo(() => { return debounce(handleQuery,800) }, [handleQuery]) //返会给父组件query值 const handleChange = (e) =>{ let val = e.currentTarget.value setQuery(val) } return ( <SearchWrapper> <div className="search_box"> <input type="text" className='box' placeholder='搜索菜单' onChange={handleChange} ref={queryRef}> </input> <i className='iconfont icon-sousuo' onChange={handleChange}></i> </div> </SearchWrapper> ) })
- 这里我仿造
- useMemo
- 这里是一个很适合用到
useMemo
的地方,因为当fatherquery
改变的时候会触发useEffect
重新渲染
整个子页面,但是我们handleQuery
函数却不用每次都执行,useMemo()会记住这次运行的结果,是一个性能优化
的好帮手,在跨页面数据流动减少复杂状态更新
的地方常常用到。 - 例如网站首页加载了很多图片,但是我们跳到其他页面再回来又需要重新渲染这个页面,十分浪费性能,这种类似的情况就可以用到
useMemo()
- 这里是一个很适合用到
- CSSTransition
- 这个是用来实现点击搜索后,页面
从右到左划过
的效果,需要的可以去仓库拉去样式
- 这个是用来实现点击搜索后,页面
3.2、懒加载
- 在菜单展示页面和搜索出来的菜品都有
lazyload效果
。 lazyload
的实现在今天已经非常简单了,以前可能还需要手写判断视口
,或者用他人写好的工具库
。- 我们只需要
npm i react-lazyload
- 在
img
遍历的过程中加入Lazyload组件
,并准备好替换图片
放在placeholder
上{/*代码实现*/} <div className="good"> {/* lazyload组件,用placeholder存放懒加载时的图片 */} <Lazyload placeholder={ <img width="120%" height="100%" src={loading} />}> <img src={goodItem.img} alt=""/> </Lazyload> <div className="name">{goodItem.goods}</div> </div>
3.3、首页
- 首页差不多做到了
1:1
复刻,但是首页没有什么业务逻辑
,所以后续估计也不会更新首页了,会着眼于其他页面的业务进行打造,争取做到一个比较适合前端面试
的程度。 - 轮播图的效果主要是运用了
antd
的swiper
组件 - 如果首页有想了解的样式或者布局可以去仓库拉取。
const swiper1_img = [img1,img2] //items遍历轮播图的图片 const items = swiper1_img.map((item, index) => ( <Swiper.Item key={index} > <img src={item} alt="" /> </Swiper.Item> )) export default function Home() { return ( <Container> <LoopImg> <div title='循环'> {/*用items占位*/} <Swiper loop autoplay className='sw'>{items}</Swiper> </div> </LoopImg> </Container> )}
Cuarto, el final
Finalmente, espero que todos no sean tacaños con 1kb
赞
y giteestar
, lo cual es realmente importante para mí. Espero谢谢
con ansias la próxima actualización para hacer que este proyecto sea más perfecto. Y神三元大佬
los artículos recomendados, si es difícil de entender, puede comprar el suyo小册
, hay un enlace al folleto de instrucciones correspondiente
Estoy participando en el reclutamiento del programa de firma de creadores de la Comunidad Tecnológica de Nuggets, haga clic en el enlace para registrarse y enviar .