抛弃Redux,迎接React的hooks和context(二)
继续【抛弃Redux,迎接React的hooks和context(一)】文章继续介绍一些新的东西
如果你还不知道什么情况的话,建议回到前面的文章看下,做下热身了解。
样式
前面的文章我们没有做关于样式太多的操作,这里我们简单的加一些样式,使得我们的应用能够更加具有导航性
- 添加下面的样式到文件index.css
1 | .episode-layout { |
- 在index.js文件中StoreProvider下面加入下面的代码
1 | import './index.css'; |
- 在App.jsx文件中,给
<section>
标签添加className属性,让className等于film-layout - 在
<section>
标签中的state.films.map
里面的<section>
添加className,让className等于film-box - 将最后的那个
</div>
,在</React.Fragment>
标签上面的,移到<p>
标签下面。 - 最后给
<div>
标签添加属性className,让className等于header
最后App.jsx的代码如下
1 | import React from 'react'; |
让我们再次运行npm start
,如果已经启动则不需要这个操作,会自动刷新
添加功能
- 仍然是在App.jsx文件中,在包含Season和Number的
</div>
标签下面添加下面的代码
1 | <button type='button' onClick={() => toggleCreatorAction(f)}>ADD</button> |
- 在fetchDataAction函数下面添加toggleCreatorAction函数,其代码如下
1 | const toggleCreatorAction = film => { |
正如这里面写的,toggleCreatorAction函数返回一个dispatch,这个dispatch发送一个creator对象到store,你也许已经猜到了这个函数的功能。
- 打开Store.js,在reducer人中添加下面这个case在default上面
1 | case 'CREATOR_ADD': |
当点击按钮ADD的时候,CREATOR_ADD的case会更新creators数组,并将新的creator对象添加到creators中
- 打开浏览器查看开发者工具,然后点击ADD按钮将会看到creators更新变化的情况
删除功能
- 修改toggleCreatorAction函数修改后代码如下
1 | const toggleCreatorAction = film => { |
filmInCreator用来检查creators中是否已经存在film,如果存在的话则进行删除操作,filmWithoutCreator用来移除存在的film,然后用新的filmWithoutCreator来更新creators数组。
- 在Store.js中的reducer中添加一个新的case,代码如下
1 | case 'CREATOR_DEL': |
上面的功能完成后,该有的功能都差不多了,但是为了向用户展示,正在发生的事情,我们需要再做一些事情
- 修改App.jsx,修改header部分,修改后的代码如下
1 | <header> |
- 修改组件,用下面的代码替换掉ADD
1 | {state.creators.find(creator => creator.id === f.id) ? 'DEL' : 'ADD'} |
这段代码使用了 array.find 方法,为了检查film对象的id是否存在于creators数组中,如果存在,则显示DEL
- 小样式的修改,在
<div>{f.name}</div>
下面的<section>
,给<section>
标签添加一个style,代码如下
1 | style={{ display: 'flex', justifyContent: 'space-between' }} |
希望一切顺利,你有代码在浏览器中类似如下。
分隔代码
前面做了一些基本逻辑上的实现操作,下面做一些关于代码拆分的操作
- 创建一个新的文件,叫做FlimList.jsx,其代码如下
1 | import React from 'react'; |
你可能已经明白我们要做的事情了
- 在App.jsx文件中,复制
state.films.map
的代码,然后粘贴到creators文件中。 - 在FilmList.jsx中将
state.films.map
替换为return films.map
- 将
state.creators.find
替换为creators.find
所有步骤做完后,FilmList.jsx文件中的代码看起来如下
1 | import React from 'react'; |
suspense 和 lazy
- 在App.jsx文件中加入下面的代码
1 | const FilmList = React.lazy(() => import('./FilmList')); |
- 在
<React.Suspense>
嵌套标签<React.Fragment>
<React.Suspense>
标签应该有下面这个属性
1 | **fallback**={<div>Loading...</div>} |
- 移除
<section className="film-layout">...</section>
部分的代码,并用<FilmList {...props} />
替换 - 添加下面的代码在返回组件的上面
1 | const props = { |
以上所有操作做完之后,保存代码并刷新浏览器应该会正常工作,并且在打开的时候会有一个’Loading…’状态
参考自:https://medium.com/octopus-labs-london/replacing-redux-with-react-hooks-and-context-part-2-838fd20e6739