纵有疾风起
人生不言弃

React简书开发实战课程笔记——4

一、styled-components 扩展

React中, 一个文件中引入css样式表后,其他所有js文件中都可以使用这个样式表,也就是说css样式表是全局的,这样可能会造成样式冲突,所以借助第三方模块:styled-components,可以让css样式表只对指定的组件起作用

  • 安装:npm install styled-components --save
  • 使用:

这个扩展不是把样式写在css文件中,而是写在js文件中(有点奇葩啊)。

新建一个js文件用于写样式(后面就叫这个js文件为样式文件)。

  • 由于有的css样式还是需要公用的,比如reset.css样式表,所以下面先介绍下怎么公用样式:

    import {  injectGlobal } from 'styled-components';  //injectGlobal 是styled-components的一个API
    
    //将css代码写在injectGlobal后面的反引号里,就可以公用这些css代码
    injectGlobal` body { margin: 0; padding: 10px; font-family: sans-serif; } `
    
  • 其他需要对单个组件生效的css代码需要这样写:

    样式文件:

    const HeaderWrapper = styled.div` color: red; `;
    const Logo = styled.a` width: 100px; `;
    

    其实就是将html标签和css样式定义为一个组件,然后再使用这个组件。最终还是会被浏览器解析成真正的html标签

    组件文件:

    render () { 
      return (
        <HeaderWrapper>
          <Logo></Logo>
        </HeaderWrapper>
      )
    }
    
  • 在这个里面你可以使用scss的语法,比如:

    const Logo = styled.input` border: 1px solid #000; &.focused { border: 1px solid blue; } &:placeholder { color: #999; } `;
    
  • 如果要使用属性,比如:a标签的href属性,有两种写法:

  1. const Logo = styled.a` color: #000; `;
    render () { 
      return (
        <Logo href="#"></Logo>  //和正常的html标签用法一样
      )
    }
    
  2. const Logo = styled.a.attrs({   //将属性写成对象的形式
      href: '#',
    })` color: #000; `;
    
  • 如果要用css添加图片,比如:background: url('./logo.png');,这种传统的写法就不行了。需要另一种写法:

    import logoImg from './logo.png';  //需要先将图片文件引入
    
    const Logo = styled.a` width: 100px; background: url(${ logoImg}); `;
    
二、拆分reducer.js

如果只有一个reducer的话,随着业务逻辑的增加,代码会变的愈来愈多,reducer会变得越来越大,所以最好将其拆分成不同的块,每个块对应一个reducer.js文件。

比如: 网页头部的state拆分到headerReducer.js中。

下面是如何将所有的reducer文件连接起来:

import {  combineReducers } from 'redux';  //combineReducers是redux中的一个API,用于连接多个reducer
import headerReducer from './headerReducer.js';  //引入拆分出去的reducer
import footerReducer from './footerReducer.js';

const reducer =  combineReducers({ 
  header: headerReducer,
  footer: footerReducer 
});

export default reducer;

拆分之后再使用state中的数据就不能直接:this.state了,需要这样写:this.state.header.xxx,即需要指明: 是state下哪个块的数据

三、immutable

用于将对象设置为不可更改
可用于保护state,state是不允许修改的,为了防止误修改,可以借助immutable库

  • 安装:npm install immutable

  • 使用:

    在用到state的文件里加上这句话:

    import {  fromJS } from 'immutable';
    

    然后:

    const defaultStore = fromJS({   //immutable中的fromJS方法将state数据保护起来
      value: ''
    });
    

    之后如果要使用或者更改注意:这里说的更改并不是真正的修改state就要使用immutable提供的setget方法:

    this.state.set('value', 'hello');
    
    console.log(this.state.get('value'););
    
    //如果要同时更改多个state,有两种方法:
    //1、
    this.state.set().set().set()...
    
    //2、
    this.state.merge({ 
      value: 'hello',
      list: ["hello", "world"]
    });
    

    这里说明一下为什么用immutable设置state为不可修改之后还能更改state。

    set的原理是这样的: 根据以前的state传入的数据,返回一个新的state。这样修改state的目的实现了,但实际state并没有修改。所以,使用immutable不仅保护了state,而且又可以愉快的修改了~

四、redux-immutable
  • 安装:npm install redux-immutable

  • 使用:

    import {  combineReducers } from 'redux';
    改为:
    import {  combineReducers } from 'redux-immutable';
    
    //如果要get有子目录的state,比如:state.header.value //state下的header下的value
    //使用redux-immutable之后,就不能再向immutable那样使用了(this.state.header.get('value'))
    //必须给header也要加上get方法:
    this.state.get('header').get('value');
    
    //可以简写成:
    this.state.getIn(['header', 'value']);  //注意书写顺序
    
五、react-router

作用就是根据不同的url,显示不同的页面信息

  • 安装:npm install react-router-dom
  • 使用:
import {  BrowserRouter, Route } from 'react-router-dom';

<BrowserRouter>
  <div>  //BrowserRouter中只能有一个元素,所以包裹一个div
    <Route path='/' exact component={ Home}></Route>
    <Route path='/detail' exact component={ Detail}></Route>
  </div>
</BrowserRouter>

说一下其中的exact,作用是让路径完全匹配,否则,当访问/detail目录时,同时也会访问到根目录/

有错误或不足,欢迎评论指正~

待续…

未经允许不得转载:起风网 » React简书开发实战课程笔记——4
分享到: 生成海报

评论 抢沙发

评论前必须登录!

立即登录