keepalive-react-component注意事项

官网

keepalive-react-component - npm

KeepAliveProvider包裹路由组件

 App.js里用KeepAliveProvider包裹路由 

 arrRoutes就是自定义的路由

 withKeepAlive 

 withKeepAlive包裹的组件需要是可滚动的,默认是window

如图所示,withKeepAlive返回的组件可以放在Suspense里,不影响使用 

源码

源码其实只有一个文件,直接复制代码也能用.

下图是自定义了className,

 

经过测试发现,下图的css值不写也正常

//"use strict"

Object.defineProperty(exports, "__esModule", { value: true })

function _interopDefault(ex) {
  return ex && typeof ex === "object" && "default" in ex ? ex["default"] : ex
}

var React = require("react")
var React__default = _interopDefault(React)

function ownKeys(object, enumerableOnly) {
  var keys = Object.keys(object)

  if (Object.getOwnPropertySymbols) {
    var symbols = Object.getOwnPropertySymbols(object)

    if (enumerableOnly) {
      symbols = symbols.filter(function (sym) {
        return Object.getOwnPropertyDescriptor(object, sym).enumerable
      })
    }

    keys.push.apply(keys, symbols)
  }

  return keys
}

function _objectSpread2(target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = arguments[i] != null ? arguments[i] : {}

    if (i % 2) {
      ownKeys(Object(source), true).forEach(function (key) {
        _defineProperty(target, key, source[key])
      })
    } else if (Object.getOwnPropertyDescriptors) {
      Object.defineProperties(target, Object.getOwnPropertyDescriptors(source))
    } else {
      ownKeys(Object(source)).forEach(function (key) {
        Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key))
      })
    }
  }

  return target
}

function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true,
    })
  } else {
    obj[key] = value
  }

  return obj
}

function _extends() {
  _extends =
    Object.assign ||
    function (target) {
      for (var i = 1; i < arguments.length; i++) {
        var source = arguments[i]

        for (var key in source) {
          if (Object.prototype.hasOwnProperty.call(source, key)) {
            target[key] = source[key]
          }
        }
      }

      return target
    }

  return _extends.apply(this, arguments)
}

function _slicedToArray(arr, i) {
  return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest()
}

function _arrayWithHoles(arr) {
  if (Array.isArray(arr)) return arr
}

function _iterableToArrayLimit(arr, i) {
  var _i = arr && ((typeof Symbol !== "undefined" && arr[Symbol.iterator]) || arr["@@iterator"])

  if (_i == null) return
  var _arr = []
  var _n = true
  var _d = false

  var _s, _e

  try {
    for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
      _arr.push(_s.value)

      if (i && _arr.length === i) break
    }
  } catch (err) {
    _d = true
    _e = err
  } finally {
    try {
      if (!_n && _i["return"] != null) _i["return"]()
    } finally {
      if (_d) throw _e
    }
  }

  return _arr
}

function _unsupportedIterableToArray(o, minLen) {
  if (!o) return
  if (typeof o === "string") return _arrayLikeToArray(o, minLen)
  var n = Object.prototype.toString.call(o).slice(8, -1)
  if (n === "Object" && o.constructor) n = o.constructor.name
  if (n === "Map" || n === "Set") return Array.from(o)
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen)
}

function _arrayLikeToArray(arr, len) {
  if (len == null || len > arr.length) len = arr.length

  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]

  return arr2
}

function _nonIterableRest() {
  throw new TypeError(
    "Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
  )
}

var CacheContext = /*#__PURE__*/ React__default.createContext()

var CREATE = "CREATE" //创建

var CREATED = "CREATED" //创建成功

var ACTIVE = "ACTIVE" //激活

var DESTROY = "DESTROY" //销毁

function cacheReducer() {
  var cacheStates = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}

  var _ref = arguments.length > 1 ? arguments[1] : undefined,
    type = _ref.type,
    payload = _ref.payload

  switch (type) {
    case CREATE:
      return _objectSpread2(
        _objectSpread2({}, cacheStates),
        {},
        _defineProperty({}, payload.cacheId, {
          scrolls: {},
          cacheId: payload.cacheId,
          element: payload.element,
          status: CREATE,
        })
      )

    case CREATED:
      return _objectSpread2(
        _objectSpread2({}, cacheStates),
        {},
        _defineProperty(
          {},
          payload.cacheId,
          _objectSpread2(
            _objectSpread2({}, cacheStates[payload.cacheId]),
            {},
            {
              doms: payload.doms,
              status: CREATED,
            }
          )
        )
      )

    case ACTIVE:
      return _objectSpread2(
        _objectSpread2({}, cacheStates),
        {},
        _defineProperty(
          {},
          payload.cacheId,
          _objectSpread2(
            _objectSpread2({}, cacheStates[payload.cacheId]),
            {},
            {
              status: ACTIVE,
            }
          )
        )
      )

    case DESTROY:
      return _objectSpread2(
        _objectSpread2({}, cacheStates),
        {},
        _defineProperty(
          {},
          payload.cacheId,
          _objectSpread2(
            _objectSpread2({}, cacheStates[payload.cacheId]),
            {},
            {
              status: DESTROY,
            }
          )
        )
      )

    default:
      return cacheStates
  }
}

function KeepAliveProvider(props) {
  var _useReducer = React.useReducer(cacheReducer, {}),
    _useReducer2 = _slicedToArray(_useReducer, 2),
    cacheStates = _useReducer2[0],
    dispatch = _useReducer2[1]

  var mount = React.useCallback(
    function (_ref) {
      var cacheId = _ref.cacheId,
        element = _ref.element

      if (cacheStates[cacheId]) {
        var cacheState = cacheStates[cacheId]

        if (cacheState.status === DESTROY) {
          var doms = cacheState.doms
          doms.forEach(function (dom) {
            return dom.parentNode.removeChild(dom)
          })
          dispatch({
            type: CREATE,
            payload: {
              cacheId: cacheId,
              element: element,
            },
          })
        }
      } else {
        dispatch({
          type: CREATE,
          payload: {
            cacheId: cacheId,
            element: element,
          },
        })
      }
    },
    [cacheStates]
  )
  var handleScroll = React.useCallback(
    function (cacheId, _ref2) {
      var target = _ref2.target

      if (cacheStates[cacheId]) {
        var scrolls = cacheStates[cacheId].scrolls
        scrolls[target] = target.scrollTop
      }
    },
    [cacheStates]
  )
  return /*#__PURE__*/ React__default.createElement(
    CacheContext.Provider,
    {
      value: {
        mount: mount,
        cacheStates: cacheStates,
        dispatch: dispatch,
        handleScroll: handleScroll,
      },
    },
    props.children,
    Object.values(cacheStates)
      .filter(function (cacheState) {
        return cacheState.status !== DESTROY
      })
      .map(function (_ref3) {
        var cacheId = _ref3.cacheId,
          element = _ref3.element
        return /*#__PURE__*/ React__default.createElement(
          "div",
          {
            id: "cache_".concat(cacheId),
            key: cacheId,
            ref: function ref(dom) {
              var cacheState = cacheStates[cacheId]

              if (dom && (!cacheState.doms || cacheState.status === DESTROY)) {
                var doms = Array.from(dom.childNodes)
                dispatch({
                  type: CREATED,
                  payload: {
                    cacheId: cacheId,
                    doms: doms,
                  },
                })
              }
            },
          },
          element
        )
      })
  )
}

function withKeepAlive(OldComponent, _ref) {
  var _ref$cacheId = _ref.cacheId,
    cacheId = _ref$cacheId === void 0 ? window.location.pathname : _ref$cacheId,
    _ref$scroll = _ref.scroll,
    scroll = _ref$scroll === void 0 ? false : _ref$scroll
  return function (props) {
    var _useContext = React.useContext(CacheContext),
      mount = _useContext.mount,
      cacheStates = _useContext.cacheStates,
      dispatch = _useContext.dispatch,
      handleScroll = _useContext.handleScroll

    var ref = React.useRef(null)
    React.useEffect(
      function () {
        if (scroll) {
          ref.current.addEventListener("scroll", handleScroll.bind(null, cacheId), true)
          // if (_ref.gaga) {
          //   ref.current = document.getElementById("bigwrap")
          //   ref.current.addEventListener("scroll", handleScroll.bind(null, cacheId), true)
          // } else {
          //   ref.current.addEventListener("scroll", handleScroll.bind(null, cacheId), true)
          // }
        }
      },
      [handleScroll]
    )
    React.useEffect(
      function () {
        var cacheState = cacheStates[cacheId]

        if (cacheState && cacheState.doms && cacheState.status !== DESTROY) {
          var doms = cacheState.doms
          doms.forEach(function (dom) {
            return ref.current.appendChild(dom)
          })

          if (scroll) {
            doms.forEach(function (dom) {
              if (cacheState.scrolls[dom]) dom.scrollTop = cacheState.scrolls[dom]
            })
          }
        } else {
          mount({
            cacheId: cacheId,
            element: /*#__PURE__*/ React__default.createElement(
              OldComponent,
              _extends({}, props, {
                dispatch: dispatch,
              })
            ),
          })
        }
      },
      [cacheStates, dispatch, mount, props]
    )
    return /*#__PURE__*/ React__default.createElement("div", {
      id: "keepalive_".concat(cacheId),
      className: "wsjkeepalive",
      ref: ref,
    })
  }
}

// exports.KeepAliveProvider = KeepAliveProvider
// exports.withKeepAlive = withKeepAlive
export { KeepAliveProvider, withKeepAlive }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值