React相关技术梳理

前一阶段借着统计的需求,先对elasticsearch进行聚合进行了探索,并以此进行了开发;后又python数据分析进行了复习与强化,虽然在pandas使用以及数据建模方面还有很多可以深入的空间,但目前阶段,先暂停一下。
下一阶段的开发,要做三维模型的工作,趁着还没开始,对端侧的技术,进行梳理.

概述

上次对前端技术进行探索,已经是去年4月份的事了,回头想想,颇多感触,旧路重走,应该有新的思路与规划
从内容上看,不仅包括web端了,还需要包括Android端
从路线上看,先回顾一下React基础与Android基础 => 再从MVC、MVVM、MVP出发,结合Redux的思路,挖掘一下端侧在数据与显示方面的共性 => 最后理解一下端侧的框架,进行实践

回顾主要参考自己的博客: 博客

React

View的展示,本质上就是树型结构,Document就是一层一层的xml标签,而xml就是树型结构

基本概念:

=> JSX元素、组件

=> props、state:单向流

=> 生命周期函数

=> 状态提升:反向流

=> 事件、 列表、表单等

=> ref

React的这块理念还是挺不错的:
把UI划分出组件层级
用React创建一个静态版本
定义UI状态的最小且完整表示
确定State应该位于哪里
添加反向数据流

根据显示切分组件 => 根据显示确定数据 => 根据交互确定反向数据

=> 下一步再刷一遍官网:
官网
实践

   基本概念 => 高级应用 => 实践

这个对reace的Element的理解很有趣:
An element is like a single frame in a movie: it represents the UI at a certain point in time.

Redux

基本原理

redux原理.png
redux 实现原理

redux核心包括:view、action、store、reducer。view发送action到store,store调度相应的reducer对状态进行转换并发送会store,store通知component状态发生变化。

细节如下:
dispatch.png

结合以上两个图可以看出,store有2个功能:Dispatcher(调度)、store(存储)

另外,触发一般是用户从view发起的,这个模型可以简化成3部分:view、store、reducer。view发起action,接受state变化,更新视图。store主要是调度action与存储状态,reducer根据action与现有的state计算新的state。如下图:

redux简图

redux简介

react-redux

在页面上,也将控制与显示做分离

react-rudex

react-redux是在react组件基础上做了一点封装,建立了component与store之间的双向关系,mapDispatchToProps是component向store发送action,mapStateToProps是store的state改变后通知component进行render。

  • Provider组件:

    包裹App,自动将store中的state与component进行关联

  • Connect方法:

    对componet进行装饰,将组件与数据进行连接

redux vs mvc

联系没有redux的场景,将component作为view,然后写一个controller,里边包含着逻辑,以及对Model的操作,这时没有专门的位置存model,可以放到controller中。
更进一步,可以在controller与多个component之间做Observer模式,当model发生变化(由于action引起)时,通知相应component进行刷新。
这里view的数据基本都是在controller中的,这样与redux的store很相似了。redux在此基础之上又对action与reducer(状态迁移)进行了封装。

这里看一下:

mvc vs mvp vs mvvm
mvc vs redux
我不太赞同上边这篇文章,我觉得store本身就是controller,增加了状态机的概念,将触发封装成action,将状态的改变逻辑封装成reducer,辅佐store。

Router

  • Router、Route、Link 3元素

  • 栈结构

    • link中可以用replace属性,替换而不是压栈

    ​ 这说明Router的数据结构是栈。

    • 压栈与出栈

      利用history进行重定向、前进、后退
      this.props.history.push("/url"),就可以进行跳转

      在url后可以增加参数
      this.props.history.push("/url", {msg: "数据"})
      数据同样是在this.props.location.state下。

      this.props.history.go(1),前进
      this.props.history.go(-1), 后退

  • link中可以用对象

    Link 中 exact精确匹配

     <Link to = { {pathname="", search="?username=admin", hash="#abc", state={msg: 'helloworld'} } } >
    
    let obj = {pathname="", search="?username=admin", hash="#abc", state={msg: 'helloworld'} }
    <Link to = {obj}>
    

    pathname: a的地址
    search: query
    state:给component传递的数据

    对于跳转到的component,可以从props.location.state中获取传递的state数据

  • id实现动态路由
    在route中可以用:id
    propos.match.param.id

  • Switch
    没有switch时,所有匹配上route的component都会显示,有了Switch则仅会匹配一个

  • Redirect
    可以通过Redirect重定向到相应的route
    同样

React Hook

通过React Hook对function component进行赋能,使其不仅能使用state(useState)、life style(useEffect)等管理,还赋能组件间数据的传递(useContext)、组件刷新的调优(useMemo)、ref的使用(useRef)等,这里简单进行记录。

react hook有2个原则:

  1. 只在funtion component中调用

  2. 只在top level调用,不要在循环、条件、子函数中调用

官方文档知乎指南使用案例

  • useState

    useState使function组件也能像class组件一样使用state

    import React, { useState } from 'react';
    function Example() {
      // Declare a new state variable, which we'll call "count"
      const [count, setCount] = useState(0);
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    
  • useEffect

    useEffect使function组件使用生命周期函数,它可以简单看做class组件中componentDidMount,componentDidUpdate、componentWillUnmout的合并。执行componentWillUnmount时候,是使用了clean up功能,类似于析构函数,进行一些释放、清理工作。在useEffect中返回一个函数。

    import React, { useState, useEffect } from 'react';
    
    function Example() {
      const [count, setCount] = useState(0);
    
      // Similar to componentDidMount and componentDidUpdate:
      useEffect(() => {
        // Update the document title using the browser API
        document.title = `You clicked ${count} times`;
      });
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    

    在useEffect中可以return一个函数,这时候就是使用cleanup,等价于componentWillUnmount

  • useContext

    useContext很神奇,它使数据在组件层级结构间传递更方便。通过它,可以将爷组件的数据,不经过父组件,直接传递给孙组件。简直就是小redux。

    示例

  • useMemo

    useMemo,memo指的是memory即记忆。它是对耗时操作的一种优化。它有2个参数,一个是耗时操作的函数,另一个是依赖的数据。只有当依赖的数据发生变化的时候,耗时操作才会进行,这样就屏蔽掉一些额外的render操作额外的耗时操作,进而提高性能。

    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
    
  • useRef

    useRef使function组件能够使用ref,与class的createRef()类似。

    function TextInputWithFocusButton() {
      const inputEl = useRef(null);
      const onButtonClick = () => {
        // `current` points to the mounted text input element
        inputEl.current.focus();
      };
      return (
        <>
          <input ref={inputEl} type="text" />
          <button onClick={onButtonClick}>Focus the input</button>
        </>
      );
    }
    
  • useImperativeHandle && forwordRef && useRef

    useImerativeHandle可以暴露function组件给其父组件的ref使用。它要配合forwordRef、useRef一起使用才可。

    function FancyInput(props, ref) {
      const inputRef = useRef();
      useImperativeHandle(ref, () => ({
        focus: () => {
          inputRef.current.focus();
        }
      }));
      return <input ref={inputRef} ... />;
    }
    FancyInput = forwardRef(FancyInput);
    

    在其父组件中通过<FancyInput ref={inputRef} />就可以使用ref,并可以调用inputRef.current.focus().

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×