让前端飞

React-慕课网简书项目实战(一)

2020-03-20  本文已影响0人  文艺的程序狗

环境准备

  1. nodejs安装

  2. npm安装

  3. 脚手架 create-react-app

    1. 安装(npm install -g create-native-app)

    2. 创建项目 create-native-app todolist

    3. 启动 npm start(这个时候项目http://localhost:3000/ 已经启动)

  4. 结构介绍

    1. package.json 依赖的包

    2. node_module 依赖

    3. public icon html

    4. src 源代码 index.js 程序入口


      image.png
  5. src关键文件介绍

    1. index.js 入口
import React from 'react';

import ReactDOM from 'react-dom';

import App from './App';

//pwA progressive web application 断网了,依然可以使用

//import * as serviceWorker from './serviceWorker';

//把app组件挂载到 id等于root的DOM组件下

//jsx语法 在 react

//如果要使用自己创建组件 自己组件必须以大写开头 App

ReactDOM.render(<App />, document.getElementById('root'));
  1. App.js
import React from 'react';

const  Component = React.Component

//render 里面的标签 不是html标签是React里面的

class App extends Component{

  render(){

    //JSX

    return (

    <div className="App">

     hello woarld

    </div>

  );

  }

}

// function App() {

//   return (

//     <div className="App">

//      hello world

//     </div>

//   );

// }

export default App;

React基础部分

  1. 基本语法

    1. bind(this) 绑定对象 ES6 还可以传其他参数

    2. 表达式{ }

    3. state 保存值

    4. 改变值 setState({})

    5. […this.state.list] ES6追加数组值

    6. list.map((item,index) => {})循环数组

    7. 事件 onClick onChange

    8. Fragment 占位符

  2. JXS细节

    1. 注释 {/xx/}或者//

    2. class className for htmlFor

    3. 显示不被转义(dangerouslySetInnerHtml)

  3. 代码优化

    1. jsx里面内容太多抽取方法

    2. bind(this)放在构造函数

    3. setState 把对象替换成函数 preValue 异步 ES6 可以不要return

  4. 组件拆分和传值

    1. 拆分

    2. 传值

      1. 父传子:通过属性的形势可以传字段以及方法(方法需要bind(this))

      2. 子调用父组件方法

      3. 组件是树形结构

      4. 细节:通过构造函数 bind(this)

  5. React思考

    1. 声明式开发(JQuery是命令式框架 直接操作DOM)

    2. 可以和其他框架共存

    3. 组件化

    4. 单向数据流

    5. 视图层框架

    6. 函数式编程

React高级

  1. 调试工具 chmod react

  2. PropTypes & DefaultProps 对属性进行类型的限制以及默认值的设定


Persion.propTypes = {

    name:PropTypes.string.isRequired;

}
  1. state或props变化会调用render函数导致界面刷新(父render调用会调用所有子render)

  2. 虚拟DOM理解(本质上是JS对象,比较JS对象不怎么耗性能,比较DOM耗性能)

    1. 步骤

      1. state数据

      2. JSX数据

      3. 生成虚拟的DOM <div id =‘abc’><span>nice</span></div> [‘div’,{id:’abc’},[span,{},’nice']]

      4. 数据 + 模板 生成真实的DOM ,显示

      5. state发生变化

      6. 数据 + 模板 生成新的虚拟DOM<div id =‘abc’><span>nice</span></div> [‘div’,{id:’abc’},[span,{},’haha']]

      7. 新的虚拟DOM与原始的虚拟DOM进行对比,找到span的内容

      8. 直接操作DOM,改变span中的内容

    2. JSX底层相当于 React.createElement()

    3. Diff方法 (多次setState合并多次,同层比对:一个不一样,下面全部替换;key值提高性能,所以尽量不要用index,保持key值稳定)

    4. ref 帮助获取DOM

      1. <ul ref={(ul) => {this.ul = ul}}></ul>

      2. 计算DOM不及时,因为setState异步,放在setState第二个参数(一个函数)

  3. 生命周期

    1. Initialization

      1. set props and state
    2. Mounting

      1. componentWillMount 组件要被挂载的时候调用(调用一次)

      2. render

      3. componentDidMount 组件挂载成功之后调用 (调用一次)

    3. Update(props || state)

      1. componentWillReceiverProps(子组件) 子组件接收到属性的时候并且子组件已经存在父组件的时候调用

      2. shouldComponentUpdate 拦截是否需要更新组件

      3. componentWillUpdate 组件每次更新前会被调用

      4. render

      5. componentDidUpdate 组件每次更新完成会被调用

    4. UnMonunting

      1. componentWillUnMounting 组件被移除的时候被调用
  4. 生命周期使用场景

    1. 判断子组件是否需要被刷新shouldComponentWillUpdate。因为父组件执行render子组件就会执行render方法(即使没有props变化),这时候要进行content属性变化的判断来进行拦截(该周期方法接受两个参数 nextProps nextState)

    2. 在componentWillMount进行 axios请求(axios引入模块通过 yarn add axios)

  5. 动画

    1. CSS3过渡动画 transition @keyFrames show-item{}

    2. react-transition-group(https://reactcommunity.org/react-transition-group/css-transition)

      1. 设置classNames=‘fade'

      2. 在css编写

        1. fade-enter ,fade-enter-active,fade-enter-done进场动画

        2. fade-exit,fade-exit-active ,fade-exit-done,出场动画

        3. fade-appear,fade-appear-active第一次渲染动画 appear={true}

        4. onEntered={(el) => {el.style.color='blue'}}在js写样式,进场完成

        5. unmountOnExit 消失 不占位置

        6. TransitionGroup 批量动画

Redux基础

  1. 概念

    1. Component 借书人

    2. Action Creator 要借什么书(事件)

    3. Store 图书管理员(处理数据)

    4. Reducers 记事本(记录)

  2. 步骤

    1. 创建store文件夹

    2. index.js(store) createStore 创建store 唯一性,只有它能改变store的值

    3. reducers.js 纯函数(固定输入,固定输出,没有副作用),输入两个参数 state action,不能修改state

    4. 引入之后调用 store.dispatch,store.subscriber store.getState

  3. 工具

    1. chmod插件 redux
  4. 优化

    1. 对action Type进行处理,新建一个actionTypes.js定义action常量

    2. 对action进行处理,新建一个actionCreators.js 统一新建事件,相当于Action Creator

Redux进阶

  1. UI组件和容器组件

  2. 无状态组件(当一个普通的组件只有render函数,直接写成函数就可以了,性能更高)

const ToDoListUI = (props) => {

return (<div>nice</div>);

}

  1. Redux-thunk中间件

    1. store引入thunk
import {createStore,applyMiddleWare,compose} from ‘redux’;

import reducer from ‘./reducer’;

import thunk from ‘redux-thunk’

const componseEnhancers = window._REDUX_DEVTOOL_EXTENDSION_…..

const enhancer = componseEnhancers(applyMiddleWare(thunk),);

const store = createStore(reducer,enhancer);

export default store;
  1. 创建action,本来只能返回对象,现在支持返回函数
//actionCreators.js

export const getToDoList = () => {

return (dispatch) => {

        axios.get(‘/list.json’).then((res) =>{

            const data = res.data;

            const action = initListAction(data);//组建好返回对象

                dispatch(action)

        })

    }

}

//ToDoList.js 组件里

const action = getToDoList();

store.dispatch(action);
  1. soga中间件 generation函数,可以写多个redux文件

  2. React-Redux第三方模块

    1. Provider
<Provider store={store}>

    <ToDoList3 />

</Provider>

Provider下的组件都将获得store的内容

  1. connect
export default connect(mapStateToProps,mapDispatchToProps)(ToDoList3)

const mapStateToProps = (state) =>{

    return {

    inputValue: state.inputValue;

}`

}

const mapDispatchToProps = (dispatch) =>{

    return {

    handleInputValue(e){

        const action = {

            type: 'change_input_value',

            value: e.target.value

    }

        dispatch(action)

    }

    }

}

 value={this.props.inputValue}

onChange={this.props.handleInputValue}
  1. 理解

    1. 通过Provider组件以及存入的store,把子组件和store进行关联(state,dispath 相当于自动取值)

    2. 在组件里通过connect,第一个参数为state,第二个参数为dispath, ToDoList3直接把对应转化为属性,需要用的时候直接以属性的形式使用即可

填坑

  1. error @typescript-eslint/eslint-plugin@1.13.0: The engine "node" is incompatible with this module. Expected version "^6.14.0 || ^8.10.0 || >=9.10.0” ——————更新node
上一篇下一篇

猜你喜欢

热点阅读