react进阶

1,react的 虚拟dom


react在修改前后的虚拟dom树的比较运算,都是同级之间进行比较,这样的算法 就很高效,是O(1)常数的,

还有就是递归的算法,就比较的低效,是O(n2) ;


ReactElement.createElement = function (type, config, children) {
  var propName;

  // 初始化参数
  var props = {};

  var key = null;
  var ref = null;
  var self = null;
  var source = null;

  // 从config中提取出内容,如ref key props
  if (config != null) {
    ref = config.ref === undefined ? null : config.ref;
    key = config.key === undefined ? null : '' + config.key;
    self = config.__self === undefined ? null : config.__self;
    source = config.__source === undefined ? null : config.__source;

    // 提取出config中的prop,放入props变量中
    for (propName in config) {
      if (config.hasOwnProperty(propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
        props[propName] = config[propName];
      } 
    }
  }

  // 处理children,挂到props的children属性下
  // 入参的前两个为type和config,后面的就都是children参数了。故需要减2
  var childrenLength = arguments.length - 2;
  if (childrenLength === 1) {
    // 只有一个参数时,直接挂到children属性下,不是array的方式
    props.children = children;
  } else if (childrenLength > 1) {
    // 不止一个时,放到array中,然后将array挂到children属性下
    var childArray = Array(childrenLength);
    for (var i = 0; i < childrenLength; i++) {
      childArray[i] = arguments[i + 2];
    }
    props.children = childArray;
  }

  // 取出组件类中的静态变量defaultProps,并给未在JSX中设置值的属性设置默认值
  if (type && type.defaultProps) {
    var defaultProps = type.defaultProps;
    for (propName in defaultProps) {
      if (props[propName] === undefined) {
        props[propName] = defaultProps[propName];
      }
    }
  }

  // 返回一个ReactElement对象
  return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
};
  • 1

 入参三个, 类型 ,配置, 有无包含内容。

最终返回一个ReactElement对象,

源码


var ReactElement = function (type, key, ref, self, source, owner, props) {

                         var element = {

                 // This tag allow us to uniquely identify this as a React Element

             $$typeof: REACT_ELEMENT_TYPE, // ReactElement对象上的四个变量,特别关键

                     type: type,

                       key: key,

                      ref: ref,

                  props: props,

         // Record the component responsible for creating this element.

             _owner: owner };


return element;


}

最后发现其实是个对象

虚拟dom里做比较其实就是两个ReactElement之间的比较;这样的比较是高效的; 这就是diff算法;

然后算法完成后会拿到结果,走一个switch去匹配是否增加还是删除还是修改的操作;

2。

组件生命周期的优化

生命周期分为两类 :组件的初始化和组件的更新。

更新也分为两种(父组件的props更新,和this.setState方法的调用,最终会走向shouldComponentUpdate这个方法);

这里优化的点主要在于组件的 更新的时候:

shouldComponentUpdate(nextProps,nextState ); 这里 如果 返回true 才会往下走,如果是false那么就会打住,

这样的话 那么这边我们就可以控制传入true的次数 ,以达到最小渲染次数来减少损耗;

入参的话是个nextProps,nextState; 

这个关键的条件是 nextstate如果不同于 this.state ,那么去渲染才是高效的,而不是每次this.setState都要渲染,

setState 有个异步队列去实现更新,也就是说是异步来的, 

由于setState会导致render,所以在render函数里不要setState,否则 又来一遍。很危险。

后面会补充shouldComponentUpdate如何配合组件去优化











### React 进阶教程:高级用法与深入理解 #### 一、React 插槽(Portals) React 的插槽(Portals)是一种特殊的渲染机制,允许开发者将子节点渲染到 DOM 层次结构之外的位置。通过 `ReactDOM.createPortal` 方法,可以在不破坏现有组件层次的情况下,将某些 UI 元素放置在特定位置,比如模态框或工具提示。这种方法特别适用于需要脱离父容器样式影响的场景[^2]。 ```javascript const Modal = (props) => { return ReactDOM.createPortal( <div className="modal"> {props.children} </div>, document.getElementById('portal-root') // 渲染目标DOM节点 ); }; ``` --- #### 二、复杂的组件通信模式——Context API 随着应用程序规模的增长,传统的 props drilling 方式会变得繁琐且难以维护。React 提供了 Context API 来解决跨层级通信的需求。通过创建上下文对象并将其提供给后代组件,可以轻松实现全局状态共享[^3]。 以下是基于 Context 和 Hooks 实现的一个简单例子: ```javascript // 创建上下文 const ThemeContext = React.createContext(); // Provider 组件 function App() { const [theme, setTheme] = React.useState('light'); return ( <ThemeContext.Provider value={{ theme, setTheme }}> <Toolbar /> </ThemeContext.Provider> ); } // Consumer 组件 function Toolbar() { return ( <ThemeContext.Consumer> {({ theme, setTheme }) => ( <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}> Toggle {theme} Mode </button> )} </ThemeContext.Consumer> ); } ``` 如果使用函数组件,则可以通过 `useContext` Hook 替代 Consumer[^4]: ```javascript function Toolbar() { const { theme, setTheme } = React.useContext(ThemeContext); return ( <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}> Toggle {theme} Mode </button> ); } ``` --- #### 三、React 高级优化技术 为了提升性能和用户体验,React 推出了许多高级功能和技术,例如 Memoization 和 Refs。 ##### 1. **Memoization** 对于纯展示型组件,可以利用 `React.memo` 或 `shouldComponentUpdate` 减少不必要的重新渲染。这有助于提高大型列表或频繁更新区域的效率[^1]。 ```javascript const ExpensiveChild = React.memo((props) => { console.log('ExpensiveChild rendered'); return <div>{props.value}</div>; }); ``` ##### 2. **Refs** 当需要操作原生 DOM 节点或者访问子组件实例时,可以借助 `useRef` 或类组件中的 `ref` 属性来完成任务。 ```javascript const inputEl = useRef(null); const focusInput = () => { inputEl.current.focus(); }; return ( <> <input ref={inputEl} type="text" /> <button onClick={focusInput}>Focus Input</button> </> ); ``` --- #### 四、Redux 状态管理集成 在复杂应用中,推荐结合 Redux 进行集中化状态管理。通过 `react-redux` 库提供的 `Provider` 和 `connect`/`useSelector`,能够方便地连接 React 组件与 Redux Store。 ```javascript import { useSelector, useDispatch } from 'react-redux'; function Counter() { const count = useSelector(state => state.counter); // 订阅state变化 const dispatch = useDispatch(); // 获取dispatch方法 return ( <div> Count: {count} <button onClick={() => dispatch({ type: 'INCREMENT' })}> Increment </button> </div> ); } ``` --- #### 五、总结 上述内容涵盖了 React 中的一些重要进阶知识点,包括 Portals、Context API、Memoization、Refs 及 Redux 集成等。掌握这些技能可以帮助开发人员更高效地构建现代化前端应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值