• 深入react技术栈记录(二)


    1. 组件之间传值

    a. 父向子: 通过props

    b. 子向父: 通过回调函数,父组件事先定义好回调函数。并将回调函数传递给子组件,子组件调用回调函数,向父组件通信。

    1. 父组件中:
    getTextValue(value) {
        this.setState({
          textareaVal: value
        })
    
    <TextareaWrapper json={this.state.json} textareaVal={this.state.textareaVal} toMain={this.getTextValue.bind(this)}></TextareaWrapper>
    
    2. 子组件中:
     getTargetValue(value) {
        let targetValue = value;
        if(targetValue.length >= 100){
          Toast.info(this.props.json['hrzzmb-000148'] || '最多输入100个字')
        }
        this.setState({
          targetValue,
        });
        //将文本输入的值向父组件传递
        this.props.toMain(value)
      }
    
    
    <List>
                <TextareaItem 
                  {...getFieldProps('count')}
                  placeholder={this.props.json['hrzzmb-000147'] || '请描述此次证明的用途'}
                  rows={5}
                  count={100}
                  value={targetValue}
                  onChange={(value) => this.getTargetValue(value)}
                />
     </List>

    c. 跨级组件通信

    可以使用contex实现跨级父子组件间的通信.

     

    可以看到,我们并没有给 ListItem 传递 props,而是在父组件中定义了 ChildContext,这样从这一层开始的子组件都可以拿到定义的 context,例如这里的 color。不过 React 官方并不建议大量使用 context,因为尽管它可以减少逐层传递,但当组件结构复杂的时候,我们并不知道 context 是从哪里传过来的。
    全局变量正是导致应用走向混乱的罪魁祸首之一,给组件带来了外部依赖的副作用。在大部分情况下,我们并不推荐使用 context 。使用 context 比较好的场景是真正意义上的全局信息且不会更改,例如界面主题、用户信息等。在应用中,context 一般用于不太会改变的全局变量, 如果有需要,建议使用高阶组件.
    d.没有嵌套关系的组件通信 (发布订阅 不推荐)

    https://blog.csdn.net/roamingcode/article/details/81773673

    2.虚拟DOM

    构建一个虚拟DOM模型并不复杂,只需具备一个DOM标签所需的基本元素即可:

    标签名, 节点属性,包含样式, 属性,事件等   子节点  标识id

     Virtual DOM 中的节点称为 ReactNode,它分为3种类型 ReactElement、ReactFragment 和ReactText。其中,ReactElement 又分为 ReactComponentElement 和 ReactDOMElement

    3.生命周期

    通过反复试验,我们得到了组件的生命周期在不同状态下的执行顺序。
     当首次挂载组件时,按顺序执行 getDefaultProps、getInitialState、componentWillMount、
    render 和 componentDidMount。
     当卸载组件时,执行 componentWillUnmount。
     当重新挂载组件时,此时按顺序执行 getInitialState、componentWillMount、render 和
    componentDidMount,但并不执行 getDefaultProps。
     当再次渲染组件时,组件接受到更新状态,此时按顺序执行 componentWillReceiveProps、
    shouldComponentUpdate、componentWillUpdate、render 和 componentDidUpdate。
    当使用 ES6 classes 构建 React 组件时,static defaultProps = {} 其实就是调用内部的 getDefaultProps
    方法,constructor 中的 this.state = {} 其实就是调用内部的 getInitialState 方法。
    因此,源码解读的部分与用 createClass 方法构建组件一样。

    父组件的componentWIllMount在其子组件的componentWillMount之前调用,而父组件的componentDidMount在其子组件的componentDidMount之后调用.

    如果此时在 componentWillReceiveProps 中调用 setState,是不会触发 re-render 的,而是会进行 state 合并。且在 componentWillReceiveProps、shouldComponentUpdate 和 componentWillUpdate 中也还是无法获取到更新后的 this.state,即此时访问的 this.state 仍然是未更新的数据,需要设置 inst.state = nextState 后才可以,因此只有在 render 和 componentDidUpdate 中才能获取到更新后的 this.state。

    注意 禁止在 shouldComponentUpdate 和 componentWillUpdate 中调用 setState,这会造成循环调用,直至耗光浏览器内存后崩溃。

    4. 解密setState 机制

    当this.setState() 被调用的时候,React 会重新调用 render 方法来重新渲染 UI。
    5. fetch API

    这是由 WHATWG(Web Hypertext Application Technology Working Group,网页超文本应用技术工作小组) 提出的新一代浏览器 Ajax 请求标准,
    目前已经获得了主流浏览器的支持。新版本的 Chrome、Firefox 和 Opera 浏览器均支持fetch API,而微软的 Edge 浏览器也正在开发对 fetch 的支持。
    fetch 的用法相比于原始的 XMLHttpRequest 有着质的飞跃,比如:
    fetch('/user.json').then(response => response.json())
    .then(data => console.log('parsed json', data))
    .catch(e => console.log("Oops, error", e));

    fetch('/api/submit.json', {
    method: 'POST',
    body: `value=${value}`,
    })
    .then(response => response.json())
    .then(value => {
    if (value.ok) {
    this.setState({ comments: fetch('/api/response.json') });
    }
    }));

    fetch 的主要特点是运用 promise 来对请求作了包装,其语法非常简洁,也更具有语义化。考虑到兼容比较旧的浏览器,我们可以使用 GitHub 官方提供的 fetch 兼容库。

    6.redux

    在 Redux 中,我们并不会自己用代码来定义一个 store。取而代之的是,我们定义一个 reducer,它的功能是根据当前触发的 action 对当前应用的状态(state)进行迭代,这里我们并没有直接修改应用的状态,而是返回了一份全新的状态.Redux 提供的 createStore 方法会根据 reducer 生成 store。最后,我们可以利用 store. dispatch方法来达到修改状态的目的。

    Redux 的核心是一个 store,这个 store 由 Redux 提供的 createStore(reducers[, initialState])方法生成。从函数签名看出,要想生成 store,必须要传入 reducers,同时也可以传入第二个可选参数初始化状态(initialState)。

    在 Redux 里,负责响应 action 并修改数据的角色就是 reducer。reducer 本质上是一个函数,其函数签名为 reducer(previousState, action) => newState。可以看出,reducer 在处理 action 的同时,还需要接受一个 previousState 参数。所以,reducer 的职责就是根据 previousState 和
    action 计算出新的 newState。

    在实际应用中,reducer 在处理 previousState 时,还需要有一个特殊的非空判断。很显然,reducer 第一次执行的时候,并没有任何的 previousState,而 reducer 的最终职责是返回新的 state,因此需要在这种特殊情况下返回一个定义好的 initialState:

    // MyReducer.js
    const initialState = {
    todos: [],
    };
    // 我们定义的 todos 这个 reducer 在第一次执行的时候,会返回 { todos: [] } 作为初始化状态
    function todos(previousState = initialState, action) {
    switch (action.type) {
    case 'XXX': {
    // 具体的业务逻辑
    }
    default:
    return previousState;
    }
    }

    Redux 中最核心的 API——createStore:
    import { createStore } from 'redux';
    const store = createStore(reducers);
    通过 createStore 方法创建的 store 是一个对象,它本身又包含 4 个方法。
     getState():获取 store 中当前的状态。
     dispatch(action):分发一个 action,并返回这个 action,这是唯一能改变 store 中数据的方式。
     subscribe(listener):注册一个监听者,它在 store 发生变化时被调用。
     replaceReducer(nextReducer):更新当前 store 里的 reducer,一般只会在开发模式中调用该方法。
    在实际使用中,我们最常用的是 getState() 和 dispatch() 这两个方法。至于 subscribe() 和replaceReducer()方法,一般会在 Redux 与某个系统(如 React)做桥接的时候使用.
    7. redux与react的绑定

    react-redux 提供了一个组件和一个 API 帮助 Redux 和 React 进行绑定,一个是 React 组件<Provider/> ,一个是 connect()。

    <Provider/> 接受一个 store 作为props,它是整个 Redux 应用的顶层组件,而 connect() 提供了在整个 React 应用的任意组件中获取 store 中数据的功能。
    8. 路由

     路由嵌套

    在声明路由时,path 属性指明了当前路由匹配的路径形式。若某条路由需要参数,只用简单地加上 :参数名 即可。若这个参数是可选参数,则用括号套起来 (:可选参数)。

    路由切换无外乎使用 hashChange 或是 history.pushState。hashChange 的方式拥有良好的浏览器兼容性,但是 url 中却多了丑陋的 /#/ 部分;而 history.pushState 方法则能给我们提供优雅的 url,却需要额外的服务端配置解决任意路径刷新的问题。

    browserHistory 即 history.pushState 的实现,假如想使用 hashChange 的方式改变路由,从React Router 中使用import hashHistory 即可。




















  • 相关阅读:
    OCP 062【中文】考试题库(cuug内部资料)第13题
    OCP 062【中文】考试题库(cuug内部资料)第12题
    560. 和为K的子数组 力扣(中等) 字节面试题,不会,前缀和,hash,有尺取法的味道
    863. 二叉树中所有距离为 K 的结点 力扣(中等) bfs
    671. 二叉树中第二小的节点 力扣(简单) auto循环set
    1713. 得到子序列的最少操作次数 力扣(困难) 最长公共子序列->最长上升子序列 lower(vector) 得迭代器
    47. 全排列 II 力扣(中等) 手写练习
    328. 奇偶链表 力扣(中等) 链表练习
    21. 合并两个有序链表 力扣(简单) 链表练习
    1743. 从相邻元素对还原数组 力扣(中等) 需要思考但可以做,hash
  • 原文地址:https://www.cnblogs.com/aimeeblogs/p/11775498.html
Copyright © 2020-2023  润新知