react项目:简书


常用的css属性

常用的css属性

styled-components的使用(css样式组件)

github地址:
https://github.com/styled-components/styled-components

styled-components使用

styled-components允许您编写实际的 CSS 代码来设置组件的样式。它还删除了组件和样式之间的映射。

InnerRef

在styled-components中使用innerRef代替ref

<Input placeholder='账号' innerRef={(input)=>{this.account=input}}/>

复选框

  1. checkbox.checked属性可以用来判断复选框是否被选中
<CheckBoxWrapper>
        <CheckBox id="checkbox" type="checkbox"/>
        <CheckBoxLabel htmlFor="checkbox"/>
</CheckBoxWrapper>
const CheckBoxWrapper = styled.div`
   position: relative;
`
const CheckBoxLabel = styled.label`
    position: absolute;
    top: 0;
    left: 0;
    width: 42px;
    height: 26px;
    border-radius: 15px;
    background: #BEBEBE;
    cursor: pointer;
`;
const CheckBox = styled.input`
    opacity: 0;
    z-index:1;
    border-radius: 15px;
    width: 42px;
    height: 26px;
`;

react-transition-group的使用(设置动画)

github地址:
https://github.com/reactjs/react-transition-group

下载:

npm install @types/react-transition-group

引入:
在这里插入图片描述
使用:
在这里插入图片描述
设置动画效果:
在这里插入图片描述

redux(统一管理状态)

安装:

yarn add redux
yarn add react-redux

原理:

创建store文件夹:
在这里插入图片描述
index.js中存储数据,创建store

import { createStore } from "redux";
import Reducer from './reducer'
// 引入需要用到的reducer
const store = createStore(Reducer);

export default store

Header组件:

//在Header组件中引入connect
import { connect } from 'react-redux'

//将state状态映射到props上
const mapStateToProps = (state) => {
    return {
    	//在props中属性名为focused
        focused: state.header.focused,
    }
}

//将需要修改state的函数
const mapDispathToProps = (dispatch) => {
    return {
    	//向props中映射一个函数名为onFocusHandle
    	//当这个函数被触发时,就会让reducer更改state,页面重新渲染。
        onFocusHandle() {
        	//定义一个action
            const action = {
                type:'search_focus'
            }
            //将action传递给reducer,供reducer判断
            dispatch(action)
        },
        onBlurHandle() {
            const action = {
                type:'search_blur'
            }
            dispatch(action)
        }
    }
}
//改变暴露Header组件的方式
export default connect(mapStateToProps,mapDispathToProps)(Header)

HeaderReducer中通过传递过来的action对state进行修改,
将每个组件需要的reducer单独定义,使代码易于维护。

//state中状态的初始化
const defaultState = {
    focused:false
}

//暴露一个纯函数
export default (state = defaultState, action) => {
//对传入的action对state中的状态进行修改
    if (action.type === 'search_focus') {
        return {
            focused:true
        }
    }
    if (action.type === 'search_blur') {
        return {
            focused:false
        }
    }
    return state
}

在总的reducer中整合所有的reducer

import { combineReducers } from "redux";
import HeaderReducer from "../common/Header/store/reducer";

export default combineReducers({
    header:HeaderReducer
})

App组件中:

import React, { Fragment } from "react";
import Header from "./common/Header";
//引入store
import store from "./store";
//引入Provider组件
import { Provider } from 'react-redux'

class App extends React.Component {
    render() {
        return (
        //该<Provider>组件使 Redux store可用于任何需要访问 Redux 存储的嵌套组件。
            <Provider store={store}>
                <Header />
            </Provider>
        )
    }
}

优化

将action和constants提出来作为单独的文件。

在这里插入图片描述
actions文件:返回对象
在这里插入图片描述
constants文件
在这里插入图片描述

redux调试工具(redux-devtools)

github地址:
https://github.com/reduxjs/redux-devtools/tree/main/extension

import { createStore,applyMiddleware ,compose } from "redux";
import thunk from "redux-thunk";
import Reducer from './reducer'
// 引入需要用到的reducer
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(Reducer, composeEnhancers( 
        applyMiddleware(thunk)
      ));
export default store

immutable.js

github地址:
https://immutable-js.com/

不可变数据一旦创建就无法更改,从而使应用程序开发更加简单,无需防御性复制,并通过简单的逻辑实现高级记忆和更改检测技术。持久数据提供了一个可变 API,它不会就地更新数据,而是总是产生新的更新数据。

下载:

npm install immutable

预防state被改变,将state设置为immutable

在这里插入图片描述

immutable对象的获取和设置

设置:
在这里插入图片描述
获取:
在这里插入图片描述

redux-immutable

npm install redux-immutable

在这里插入图片描述

redux-thunk

Redux 的Thunk中间件。它允许编写内部带有逻辑的函数,这些函数可以与 Redux 存储dispatch和getState方法进行交互。允许在action中进行异步操作。

安装:
npm install redux-thunk

导入redux-thunk

//添加applyMiddleware
import { createStore,applyMiddleware,compose  } from "redux";
//引入中间件
import thunk from "redux-thunk";
import Reducer from './reducer'
// 引入需要用到的reducer
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(Reducer, composeEnhancers( 
        applyMiddleware(thunk)
      ));

export default store

axios(异步请求获取数据)

axios中文文档:
http://axios-js.com/zh-cn/docs/index.html

axios是一个基于promise的HTTP库,

安装:

npm install axios

//get请求
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

//post请求
axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

react-router-dom

BrowserRouter,Routers,Route:

npm i react-router-dom

在需要引入路由的js文件引入browserRouter和route
import { BrowserRouter , Route} from “react-router-dom”;

在route6中:

import React, { Fragment } from "react";
//引入路由相关的组件
import { BrowserRouter,Route,Routes} from "react-router-dom";
import Header from "./common/Header";
import store from "./store";
import { Provider } from 'react-redux'
import Home from "./pages/home";
import Detail from "./pages/detail";

class App extends React.Component {
    render() {
        return (
            <Provider store={store}>
                <Fragment>
                    <Header />
                    //使用BrowserRouter包裹所有与路由相关的内容
                    <BrowserRouter>
                    	//Routes与Switch中的功能相同
                    	//Routes让下面的所有路由中只有一个可以匹配到,当有一个匹配到的时候,不在进行匹配。
                        <Routes>
                        	//route6中使用element代替component
                            <Route path="/" element={<Home/>}></Route>
                            <Route path="/detail" element={<Detail/>}></Route>
                        </Routes>
                    </BrowserRouter>
                </Fragment>
            </Provider>
        )
    }
}

export default App

Link

使用Link组件代替a标签的跳转

import { Link } from 'react-router-dom'
<Link to='/'>
    <Logo />
</Link>

Link 新建一个浏览器窗口打开

_self :默认。在相同的框架中打开被链接文档。
_blank: 新开一个窗口打开文档
_parent : 在父框架集中打开被链接文档。
_top:在整个窗口中打开被链接文档。

<Link target='_blank' to='/download'>
  <NavItem className='left'>
       <i className='iconfont'>&#xe6e1;</i>
       下载App
     </NavItem>
  </Link>

Redirect/Navigate

重定向组件

relplace模式:是会将最顶上的浏览记录替换掉,
push模式:会在浏览器中的history存有记录。

<Redirect to='/'/>

<Navigate to={'/login'} replace='true'/>
//其中relplace是会将最顶上的浏览记录替换掉,
//push模式,会在浏览器中的history存有记录。
  1. 在V6中已经删除重定向redirect,替换成navigate
  2. 在V5中使用编程式导航,需要使用this.props.history对象上的API进行跳转、前进、后退。
    this.props.history.push()
    this.props.history.replace()
    this.props.history.goBack()
    this.props.history.goForward()
    this.props.history.go()

性能优化

使用PureComponent

将class app extends component替换成class app extends PureComponent

PureComponent在底层实现了shouldComponentUpdate

由于我们的组件几乎都使用了connect进行连接,所以一旦store中的数据发生了改变,所有的组件都会重新渲染,而此时存在一些组件,发生改变的数据和该组件无关,但是该组件也进行了渲染。使用shouldComponentUpdate钩子,可以通过return false的方式阻止该组件的渲染。

shouldComponentUpdate这个生命周期钩子,用于判断只有和该组件相关的数据发生改变的时候,才渲染这个组件。

其他问题

防止字符串中的html内容被转义

//在组件中设置
<Content dangerouslySetInnerHTML={{__html:this.props.content}}/>

完成“记住我”功能

未设置过期时间

1. 使用local storage记住用户的信息
const user = {
      account: account,
      password:password
    }
    // 如果复选框被选中,保存账号密码
    if (checkbox.checked) {
      localStorage.setItem('user',JSON.stringify(user))
    }
2. 在componentDidMount中获取用户的信息,如果存在,更改store中的login属性为true
componentDidMount() {
        // 获取local storage中的user
        const user =localStorage.getItem('user')
        if (user) {
            // 更改store中的login
            this.props.changeLogin()
        } 
    }
3. 点击退出按钮时,将存在store中的user属性删除。
 // 清楚local storage中保存的user信息
  localStorage.removeItem('user')

设置过期时间,在原型链上设置setExpire,getExpire

// 给local storage设置过期时间
    Storage.prototype.setExpire = (key, value, expire) => {
      let obj = {
        data: value,
        time: Date.now(),
        expire:expire
      }
      localStorage.setItem(key,JSON.stringify(obj))
    }

localStorage.setExpire('user',user,10000)

 // 给storage中添加函数,判断是否过期
        Storage.prototype.getExpire = key => {
            let val = localStorage.getItem(key)
            if (!val) {
                return val;
            }
            val = JSON.parse(val)
            if (Date.now() - val.time > val.expire) {
                localStorage.removeItem(key)
                return null
            }
            return val.data
        }


const user= localStorage.getExpire('user')

完成PC端屏幕自适应(BootStrap)

在index.html中引入

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"
    integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
  <title>React App</title>

  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
    integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
    crossorigin="anonymous"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"
    integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ"
    crossorigin="anonymous"></script>

  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"
    integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm"
    crossorigin="anonymous"></script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值