手记

【九月打卡】第16天 React零基础入门到实战,完成企业级项目简书网站开发 第七讲

课程章节: 项目实战:Header组件开发

主讲老师: Dell

课程内容:

今天学习的内容包括:

基于react的组件化思想,用styled-components对样式也进行了组件化,这样每个组件拥有了自己的功能,还拥有了自己的样式,从而能够实现真正意义上的复用。react通过state来控制组件,而styled-components也可以通过state的改变来动态的改变组件的样式。

reset.css: 不同浏览器等内核里,对浏览器等标签默认样式是不同的,为了让我们的代码在所有浏览器上表现形式是一致的,先把浏览器对一些标签的默认形式进行统一,reset.css就是解决这个问题的。

课程收获:

7.1 心得:

styled-components ,v4 已经删除了 injectGlobalStyle 全局方法, 对应解决方法是 需要把
1.用createGlobalStyle定义全局样式

import { createGlobalStyle } from 'styled-components'

export const Globalstyle = createGlobalStyle` 
body{
  margin: 0;
  padding: 0
 }

然后按照样式组件引入即可
2. 在项目主文件导入样式

import { Globalstyle } from './style'

3.以样式组件的方式当作标签引入

render() {
  return (
    <div>
      <Globalstyle/>
    </div>
);

7.2 心得:

styled-Component不会干扰其他样式的原因是因为,它将css抽离成一个组件,只用使用的时候才会引入。
它可以直接给标签添加属性,通过attrs({arrtsName: value}),也可以直接在组件上写属性。attrs上的属性优先级是大于组件上书写的属性。

// 跳转到"/123",而不是"/"
"export const Logo = styled.a.attrs({href: '/123'})"
"<Logo href="/">"

7.3 心得:

style-components实例:

搜索框重要内容:

export const NavSearch = styled.input.attrs({

    placeholder: '搜索'

})`

box-sizing:border-box;//保证总长度为设定的width

outline:none;//焦点在时搜索框外没有被选中的黑线

border-radius:19px;//设置搜索框的圆角

background:#eee;

font-size:14px;

&::placeholder {//搜索框内的文字效果 &::;若要选中某个类,则用&.xxx{}

    color:#969696

}

7.4 心得:

  1. 首先./statics/iconfont/iconfont.js中只需要把之前本地链接改成在线链接即可,@font-face这块可以直接在官网复制。还有一点是现在应该使用createGlobalStyle方法来定义全局样式。
import { createGlobalStyle } from 'styled-components';export const GlobalFontStyle = createGlobalStyle`
 @font-face {
   font-family: 'iconfont';  /* Project id 2468859 */
   src: url('//at.alicdn.com/t/font_2468859_bis8y7il1.woff2?t=1634457194883') format('woff2'),
       url('//at.alicdn.com/t/font_2468859_bis8y7il1.woff?t=1634457194883') format('woff'),
       url('//at.alicdn.com/t/font_2468859_bis8y7il1.ttf?t=1634457194883') format('truetype');
 }
 .iconfont {
   font-family: "iconfont" !important;
   font-size: 16px;
   font-style: normal;
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
 }
`;
  1. 然后在index.js中引用一下,写在<Fragment>中即可。
import React, { Fragment } from 'react';import ReactDOM from 'react-dom';import App from './App';import { GlobalStyle } from './style';import { GlobalFontStyle } from './statics/iconfont/iconfont'ReactDOM.render(
 <Fragment>
   <GlobalStyle/>
   <GlobalFontStyle/>
   <App/>
 </Fragment>,
 document.getElementById('root'))
  1. 最后按照官网给出的例子写即可。
<SearchWrapper>
 <NavSearch></NavSearch>
 <span className="iconfont">&#xe637;</span></SearchWrapper>

7.5 心得:

yarn add react-transition-group 安装动画插件

import { CSSTransition } from ‘react-transition-group’; 引入

<CSSTransition>把需要动画的元素包裹起来</CSSTransition>

再配置一下三个状态样式

.slide-enter{} //入场
.slide-enter-active{} //选中
.slide-exit{} //出厂
.slide-exit-active{} //出厂之后

7.6 心得:

子组件使用父组件中provider中传过来的数据的方法

//接收的store的数据
const mapStateToProps = (state) =>{
return{
}
}

//要修改数据时调用的dipatch方法写到里面,也就是指store.dispatch()方法

const mapDispathToProps = (dispatch) =>{
return{
}
}

export default connect(mapStateToprops,mapDispathToprops)(Header)

7.7 心得:

import { combineReducers } from 'redux';
import {reducer as headerReducer} from '../pages/header/store'

const reducer = combineReducers({
header: headerReducer
})
// 将不同页面的reducer统一合并
export default reducer

随着项目建设,如果将所有变量和逻辑都写在reducer中,会导致reducer文件变得臃肿且逻辑复杂。所以需要对reducer进行拆分。
使用"combineReducers"函数,对多个reducer进行整个,然后引出。

store/reducer.js
const reducer = combineReducer({header: componentReducer})
export default reducer

7.8 心得:

header 组件里面设置统一出口是败笔,要做太多的工作了。

在header组件内直接调用store里面的文件就好

在统一的reducer里面引用一下header的reduce

import * as actionCreators from './store/actionCreators';

要用到es6的语法,我用老师带中括号的方法提示Unexpected token错误。去掉“{}”就不报错了。

7.9 心得:

1、immutable库提供一个fromJS方法,可以把一个JS对象转换为immutable(不可变)对象;
2、使用immutable.js之后,不能用“.”访问store中的对象,要使用get()方法;
3、使用immutable.js之后,修改store中的数据时,要使用set方法;
4、immutable对象的set方法,会结合之前immutable对象的值和设置的值,返回一个全新的对象,并没有改变原始的state;

7.10 心得:

immutable.js
1.npm i immutable --save
2.header/store/reducer.js import { fromJS} from immutable
3.const initialState = fromJs({focused: false})

7.11 心得:

React只能兼容到IE8

getListArea(参数: props.focused)

Redux store 仅支持同步数据流。使用 thunk 等中间件可以帮助在 Redux 应用中实现异步性。可以将 thunk 看做 store 的 dispatch() 方法的封装器;我们可以使用 thunk action creator 派遣函数或 Promise,而不是返回 action 对象。

注意,没有 thunk 的话,默认地是同步派遣。也就是说,我们依然可以从 React 组件发出 API 调用(例如使用 componentDidMount() 生命周期方法发出这些请求),但是我们在 Redux 应用中难以实现以下两点:

可重用性(思考下合成)

可预测性,只有 action creator 可以是状态更新的单一数据源

7.12 心得:

getListArea方法,在一个普通的组件里, 没必要传‘’show’'参数了. 直接用this.props.focused

想从store取数据, 在mapStateToProps 里面去写: stage.getIn(['header]. ‘list’)

dispatch对应的方法里对应的data就是immutable的类型了, reducer接收到的action的data也会是immutable的类型了, 实现了数据统一.

map方法对数据进行循环展示每一项

传递action前,把 action里的data也转换成immutable 数组

dispatch方法, 异步axios请求数据, 如果成功了, 执行then( () => {} )方法;
如果失败了, 执行 catch方法

1、异步获取的逻辑拆分到actionCreactors, action中要求返回一个函数,用到react-thunk中间件

2、获取store数据想要改变注意,reducer外层包裹一个fromJS把内部数据类型改变成immutable数据,数据类型要统
一,把actionCreactors传递之前把action中的数据转换成immutable数据类型{impot {fromJS} from ‘immutable’;}

3、调用map()循环展示

7.13 心得:

结构赋值, const { focused, list } = this.props

mapToStateProps, 把totalPage也拿进来, 获取总页码,
如果当前页码小于totalPage, 就下页, 否则就改回第一页,.
ac里可以接收到Page这个新页码, 把新页码传递给reducer.
reducer里changePage被接收到的时候, 同时action里, 也会有page的这个属性.——是即将要替换的这个页码.

7.14 心得:

mapToStateProps, 把totalPage也拿进来, 获取总页码,
如果当前页码小于totalPage, 就下页, 否则就改回第一页,.
ac里可以接收到Page这个新页码, 把新页码传递给reducer.
reducer里changePage被接收到的时候, 同时action里, 也会有page的这个属性.——是即将要替换的这个页码.

7.15 心得:

mapToStateProps, 把totalPage也拿进来, 获取总页码,
如果当前页码小于totalPage, 就下页, 否则就改回第一页,.
ac里可以接收到Page这个新页码, 把新页码传递给reducer.
reducer里changePage被接收到的时候, 同时action里, 也会有page的这个属性.——是即将要替换的这个页码.

7.16 心得:

根据list的size属性来判断需不需要请求数据

0人推荐
随时随地看视频
慕课网APP