CJY0208 / react-activation

Hack <KeepAlive /> for React
https://www.npmjs.com/package/react-activation
MIT License
1.82k stars 141 forks source link

配合路由使用报错 #12

Closed fangzhiguo closed 4 years ago

fangzhiguo commented 4 years ago

return (<Route key={index} path={route.path} exact={route.exact} component={

我的组件,一到这里就报错了,报对象不能作为react子节点
                          }/>)  
fangzhiguo commented 4 years ago

是我的写法不对么??dome 实例都是静态导入的,我是通过import()函数动态加载的,和这个没关系吧

CJY0208 commented 4 years ago

具体是如何写的?报什么错呢

fangzhiguo commented 4 years ago

import React from 'react' import './component.scss' import Loadable from 'react-loadable' import RouteLoading from 'components/RouteLoading/index' import { Route, Switch, withRouter, HashRouter } from 'react-router-dom' import { AliveScope } from 'react-activation' const Login = Loadable({ loader: () => import('view/Login'), loading: RouteLoading })

const Main = Loadable({ loader: () => import('view/Main'), loading: RouteLoading })

class Root extends React.Component { render() { return (

{/* 含有子菜单不能严格匹配 */} {/* */}
)

} } export default Root

这个是入口

fangzhiguo commented 4 years ago

import React from 'react' import './component.scss' import { Switch, withRouter, Link, Route } from 'react-router-dom' import KeepAlive from 'react-activation' import { Layout, Menu, Icon } from 'antd'; // import AuthRouter from 'components/AuthRouter' import Header from 'components/Header' import Loadable from 'react-loadable' import RouteLoading from 'components/RouteLoading/index' // import { get, post } from 'utils/ownAxios' import OwnIcon from "components/OwnIcon" import routers from 'router/index'

import {connect} from 'react-redux' const mapStateToProps = (state) => ({ subMenulist:state.menu.subMenuList }) const { Content, Sider, Footer } = Layout;

const IndexPage = Loadable({ loader: () => import('view/IndexPage'), loading: RouteLoading, })

@connect(mapStateToProps,null) class Main extends React.Component { constructor(props) { super(props) this.state = { collapsed: false, //菜单伸缩项开关 }; } componentDidMount() { //子菜单列表是在Header头中通过redux中获取的 }

componentWillUnmount(){ this.setState = (state,callback)=>{ return; }; } toggle = () => { this.setState({ collapsed: !this.state.collapsed, }); };

render() { const { match, subMenulist } = this.props; return (

{/* 头部顶部的选项 */}
{/* 侧边的二级选项导航 */}
{/* 首页 */} <> { subMenulist.subMenuLists.map((res, index) => { //使用地址做是否选中的匹配 return {/* */} {res.showName} }) } {/* 右侧主要内容区域 */} {/* 兼容IE10 的计算属性 */} {/* 伸缩按钮 */}
{/* 路由显示区域 */}
{ routers.map((route,index) =>{ //正常的 return () //报错的 // return ({ // return ( // // {route.component} // // ) // } //}/>) }) }
{/* 底部版权相关 */}
Copyright © 青岛银行, All Rights Reserved.
      </Layout>
    </div>
)

} } export default Main

遍历路由的地方,同时也是使用组件的地方

fangzhiguo commented 4 years ago

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app

The above error occurred in the component:

Uncaught Error: Objects are not valid as a React child (found: object with keys {componentStack}). If you meant to render a collection of children, use an array instead.

index.js:1437 The above error occurred in the

component: in h1 (at ErrorBoundary/index.js:21) in ErrorBoundary (at App.js:16) in App (at src/index.js:25)

Consider adding an error boundary to your tree to customize error handling behavior. Visit https://fb.me/react-error-boundaries to learn more about error boundaries.

这些是报错内容

CJY0208 commented 4 years ago

报错处的 route.component 是组件定义而不是实例,需要调整为

<KeepAlive>
  {React.createElement(route.component)}
</KeepAlive>

// 或者

<KeepAlive>
  <route.component />
</KeepAlive>

// 另外看到一个无关的可优化部分, render 方法传递 prop 可以不一定使用 withRouter
// 可使用 props 解构传递,如下

render={props => (
  <KeepAlive>
    <route.component {...props } />
  </KeepAlive>
)}
fangzhiguo commented 4 years ago

好的,我试试,谢谢

------------------ 原始邮件 ------------------ 发件人: "CJY"<notifications@github.com>; 发送时间: 2019年11月25日(星期一) 上午9:45 收件人: "CJY0208/react-activation"<react-activation@noreply.github.com>; 抄送: "『爱Luck娃』"<985021564@qq.com>; "Author"<author@noreply.github.com>; 主题: Re: [CJY0208/react-activation] 配合路由使用报错 (#12)

报错处的 route.component 是组件定义而不是实例,需要调整为 <KeepAlive> {React.createElement(route.component)} </KeepAlive> // 或者 <KeepAlive> <route.component /> </KeepAlive> // 另外看到一个无关的可优化部分, render 方法传递 prop 可以不一定使用 withRouter // 可使用 props 解构传递,如下 render={props => ( <KeepAlive> <route.component {...props } /> </KeepAlive> )}

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

fangzhiguo commented 4 years ago
{ routers.map((route,index) =>{ //正常的 // return () //报错的 return ( }/>) }) }
fangzhiguo commented 4 years ago

index.js:1437 Warning: Failed prop type: Invalid prop 'component' supplied to 'Route': the prop is not a valid React component in Route (at component.js:108) in Main (created by Connect(Main)) in Connect(Main) (created by LoadableComponent) in LoadableComponent (created by Context.Consumer) in withRouter(LoadableComponent) (created by Context.Consumer) in Route (at component.js:27) in Switch (at component.js:25) in AliveScope (at component.js:24) in Router (created by HashRouter) in HashRouter (at component.js:23) in div (at component.js:22) in div (at component.js:20) in Root (at App.js:19) in Provider (at App.js:18) in LocaleProvider (created by Context.Consumer) in LocaleReceiver (created by ConfigProvider) in ConfigProvider (at App.js:17) in ErrorBoundary (at App.js:16) in App (at src/index.js:25)

fangzhiguo commented 4 years ago

index.js:1437 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: . Did you accidentally export a JSX literal instead of a component? in Route (at component.js:108) in Switch (at component.js:98) in div (at component.js:97) in main (created by Basic) in Basic (created by Context.Consumer) in Adapter (at component.js:96) in section (created by BasicLayout) in BasicLayout (created by Context.Consumer) in Adapter (at component.js:86) in section (created by BasicLayout) in BasicLayout (created by Context.Consumer) in Adapter (at component.js:61) in Switch (at component.js:57) in div (at component.js:56) in section (created by BasicLayout) in BasicLayout (created by Context.Consumer) in Adapter (at component.js:52) in div (at component.js:51) in Main (created by Connect(Main)) in Connect(Main) (created by LoadableComponent) in LoadableComponent (created by Context.Consumer) in withRouter(LoadableComponent) (created by Context.Consumer) in Route (at component.js:27) in Switch (at component.js:25) in AliveScope (at component.js:24) in Router (created by HashRouter) in HashRouter (at component.js:23) in div (at component.js:22) in div (at component.js:20) in Root (at App.js:19) in Provider (at App.js:18) in LocaleProvider (created by Context.Consumer) in LocaleReceiver (created by ConfigProvider) in ConfigProvider (at App.js:17) in ErrorBoundary (at App.js:16) in App (at src/index.js:25)

fangzhiguo commented 4 years ago

react-dom.development.js:26582 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of Context.Consumer. at createFiberFromTypeAndProps (react-dom.development.js:26582) at createFiberFromElement (react-dom.development.js:26604) at reconcileSingleElement (react-dom.development.js:15562) at reconcileChildFibers (react-dom.development.js:15622) at reconcileChildren (react-dom.development.js:18094) at updateContextProvider (react-dom.development.js:19771) at beginWork$1 (react-dom.development.js:20186) at HTMLUnknownElement.callCallback (react-dom.development.js:337) at Object.invokeGuardedCallbackDev (react-dom.development.js:386) at invokeGuardedCallback (react-dom.development.js:439) at beginWork$$1 (react-dom.development.js:25732) at performUnitOfWork (react-dom.development.js:24658) at workLoopSync (react-dom.development.js:24631) at performSyncWorkOnRoot (react-dom.development.js:24220) at react-dom.development.js:12264 at unstable_runWithPriority (scheduler.development.js:823) at runWithPriority$2 (react-dom.development.js:12210) at flushSyncCallbackQueueImpl (react-dom.development.js:12259) at flushSyncCallbackQueue (react-dom.development.js:12247) at scheduleUpdateOnFiber (react-dom.development.js:23658) at Object.enqueueSetState (react-dom.development.js:14057) at LoadableComponent.push../node_modules/_react@16.11.0@react/cjs/react.development.js.Component.setState (react.development.js:315) at update (index.js:240) at index.js:250 createFiberFromTypeAndProps @ react-dom.development.js:26582 createFiberFromElement @ react-dom.development.js:26604 reconcileSingleElement @ react-dom.development.js:15562 reconcileChildFibers @ react-dom.development.js:15622 reconcileChildren @ react-dom.development.js:18094 updateContextProvider @ react-dom.development.js:19771 beginWork$1 @ react-dom.development.js:20186 callCallback @ react-dom.development.js:337 invokeGuardedCallbackDev @ react-dom.development.js:386 invokeGuardedCallback @ react-dom.development.js:439 beginWork$$1 @ react-dom.development.js:25732 performUnitOfWork @ react-dom.development.js:24658 workLoopSync @ react-dom.development.js:24631 performSyncWorkOnRoot @ react-dom.development.js:24220 (anonymous) @ react-dom.development.js:12264 unstable_runWithPriority @ scheduler.development.js:823 runWithPriority$2 @ react-dom.development.js:12210 flushSyncCallbackQueueImpl @ react-dom.development.js:12259 flushSyncCallbackQueue @ react-dom.development.js:12247 scheduleUpdateOnFiber @ react-dom.development.js:23658 enqueueSetState @ react-dom.development.js:14057 push../node_modules/_react@16.11.0@react/cjs/react.development.js.Component.setState @ react.development.js:315 update @ index.js:240 (anonymous) @ index.js:250 Promise.then (async) _loadModule @ index.js:249 componentWillMount @ index.js:197 callComponentWillMount @ react-dom.development.js:14324 mountClassInstance @ react-dom.development.js:14423 updateClassComponent @ react-dom.development.js:18408 beginWork$1 @ react-dom.development.js:20148 beginWork$$1 @ react-dom.development.js:25708 performUnitOfWork @ react-dom.development.js:24658 workLoopSync @ react-dom.development.js:24631 performSyncWorkOnRoot @ react-dom.development.js:24220 scheduleUpdateOnFiber @ react-dom.development.js:23647 updateContainer @ react-dom.development.js:27056 (anonymous) @ react-dom.development.js:27473 unbatchedUpdates @ react-dom.development.js:24385 legacyRenderSubtreeIntoContainer @ react-dom.development.js:27472 render @ react-dom.development.js:27557 ./src/index.js @ index.js:24 webpack_require @ bootstrap:790 fn @ bootstrap:150 0 @ watermark.js:190 webpack_require @ bootstrap:790 checkDeferredModules @ bootstrap:45 webpackJsonpCallback @ bootstrap:32 (anonymous) @ main.chunk.js:1 index.js:1437 The above error occurred in the component: in Route (at component.js:108) in Switch (at component.js:98) in div (at component.js:97) in main (created by Basic) in Basic (created by Context.Consumer) in Adapter (at component.js:96) in section (created by BasicLayout) in BasicLayout (created by Context.Consumer) in Adapter (at component.js:86) in section (created by BasicLayout) in BasicLayout (created by Context.Consumer) in Adapter (at component.js:61) in Switch (at component.js:57) in div (at component.js:56) in section (created by BasicLayout) in BasicLayout (created by Context.Consumer) in Adapter (at component.js:52) in div (at component.js:51) in Main (created by Connect(Main)) in Connect(Main) (created by LoadableComponent) in LoadableComponent (created by Context.Consumer) in withRouter(LoadableComponent) (created by Context.Consumer) in Route (at component.js:27) in Switch (at component.js:25) in AliveScope (at component.js:24) in Router (created by HashRouter) in HashRouter (at component.js:23) in div (at component.js:22) in div (at component.js:20) in Root (at App.js:19) in Provider (at App.js:18) in LocaleProvider (created by Context.Consumer) in LocaleReceiver (created by ConfigProvider) in ConfigProvider (at App.js:17) in ErrorBoundary (at App.js:16) in App (at src/index.js:25)

fangzhiguo commented 4 years ago

我改成你说的方式,都报错,上面是报错内容!!!

CJY0208 commented 4 years ago

Route 组件需要使用 render 属性而不是 component

render={props => (
  <KeepAlive>
    <route.component {...props} />
  </KeepAlive>
)}
fangzhiguo commented 4 years ago

`

{ routers.map((route,index) =>{ //正常的 // return () return (( ) }/>) }) }
                  </div>`
fangzhiguo commented 4 years ago

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem. at resolveDispatcher (react.development.js:1556) at Object.useContext (react.development.js:1564) at HookExpand (index.js:1661) at renderWithHooks (react-dom.development.js:16296) at mountIndeterminateComponent (react-dom.development.js:18779) at beginWork$1 (react-dom.development.js:20124) at HTMLUnknownElement.callCallback (react-dom.development.js:337) at Object.invokeGuardedCallbackDev (react-dom.development.js:386) at invokeGuardedCallback (react-dom.development.js:439) at beginWork$$1 (react-dom.development.js:25732) at performUnitOfWork (react-dom.development.js:24658) at workLoopSync (react-dom.development.js:24631) at performSyncWorkOnRoot (react-dom.development.js:24220) at react-dom.development.js:12264 at unstable_runWithPriority (scheduler.development.js:823) at runWithPriority$2 (react-dom.development.js:12210) at flushSyncCallbackQueueImpl (react-dom.development.js:12259) at flushSyncCallbackQueue (react-dom.development.js:12247) at scheduleUpdateOnFiber (react-dom.development.js:23658) at Object.enqueueSetState (react-dom.development.js:14057) at LoadableComponent.push../node_modules/_react@16.11.0@react/cjs/react.development.js.Component.setState (react.development.js:315) at update (index.js:240) at index.js:250 index.js:1437 The above error occurred in the component: in HookExpand (at component.js:110) in Route (at component.js:108) in Switch (at component.js:98) in div (at component.js:97) in main (created by Basic) in Basic (created by Context.Consumer) in Adapter (at component.js:96) in section (created by BasicLayout) in BasicLayout (created by Context.Consumer) in Adapter (at component.js:86) in section (created by BasicLayout) in BasicLayout (created by Context.Consumer) in Adapter (at component.js:61) in Switch (at component.js:57) in div (at component.js:56) in section (created by BasicLayout) in BasicLayout (created by Context.Consumer) in Adapter (at component.js:52) in div (at component.js:51) in Main (created by Connect(Main)) in Connect(Main) (created by LoadableComponent) in LoadableComponent (created by Context.Consumer) in withRouter(LoadableComponent) (created by Context.Consumer) in Route (at component.js:27) in Switch (at component.js:25) in AliveScope (at component.js:24) in Router (created by HashRouter) in HashRouter (at component.js:23) in div (at component.js:22) in div (at component.js:20) in Root (at App.js:19) in Provider (at App.js:18) in LocaleProvider (created by Context.Consumer) in LocaleReceiver (created by ConfigProvider) in ConfigProvider (at App.js:17) in ErrorBoundary (at App.js:16) in App (at src/index.js:25)

React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.

fangzhiguo commented 4 years ago

改成render的报这两个错误

CJY0208 commented 4 years ago

看起来是 hook 相关的错误,你的 routers 列表是怎样的呢?

fangzhiguo commented 4 years ago

import Loadable from 'react-loadable' import RouteLoading from 'components/RouteLoading/index'

const loadable = (filename) => Loadable({ loader:() => import(view/${filename}), loading:RouteLoading, });

//路由配置对象

const routers = [ { //动态规则列表 path:'/main/rule/info/list', exact:true, isActive:false, //缓存使用的暂缺,后续待用 component:loadable('OwnRule/StaticRuleMgt') },

{ //创建规则 path:'/main/createDyRule', exact:true, isActive:false, component:loadable('OwnRule/CreateDyRule') }, { //修改规则 path:'/main/editDyRule/:name', exact:true, isActive:false, component:loadable('OwnRule/EditDyRule') }, { //规则详情 path:'/main/ruleDetail/:name', exact:true, isActive:false, component:loadable('OwnRule/RuleDetail') }, { //静态规则列表 path:'/main/rule/bean/list', exact:true, isActive:false, component:loadable('OwnRule/JtRuleMgt') }, { //创建静态规则 path:'/main/createJtRule', exact:true, isActive:false, component:loadable('OwnRule/CreatJtRule') }, { //修改静态规则 path:'/main/editJtRule/:code', exact:true, isActive:false, component:loadable('OwnRule/EditJtRule') }, { //风险列表 path:'/main/query/risk/list', exact:true, isActive:true, component:loadable('OwnRisk/RiskMgt')

}, { //风险详情 path:'/main/riskDetail/:chano/:behover/:num/:demation', //传多个参数 exact:true, isActive:false, component:loadable('OwnRisk/RiskDetail') }, { //菜单管理 path:'/main/system/menu/list', exact:true, isActive:false, component:loadable('OwnSystem/MenuMgt') }, { //添加菜单 path:'/main/addMenu', exact:true, isActive:false, component:loadable('OwnSystem/AddMenu') }, { //角色菜单 path:'/main/system/role/list', exact:true, isActive:false, component:loadable('OwnSystem/RoleMgt') }, { //用户菜单 path:'/main/system/user/list', exact:true, isActive:false, component:loadable('OwnSystem/UserMgt') }, { //添加用户 path:'/main/addUser', exact:true, isActive:false, component:loadable('OwnSystem/AddUser') }, { //添加用户 path:'/main/userAddRole/:userid', exact:true, isActive:false, component:loadable('OwnSystem/UserAddRole') },

{ //黑名单管理 path:'/main/blackList/listMgt', exact:true, isActive:false, component:loadable('OwnList/BlackList/ListMgt') } ]

export default routers;

fangzhiguo commented 4 years ago

我这都是类组件 也没用hooks

CJY0208 commented 4 years ago

很奇怪...能否先不要在路由处使用 KeepAlive,直接在页面上尝试制作一个简单的 KeepAlive 场景,确认是否是功能本身的问题呢?

function Counter() {
  const [count, setCount] = useState(0)

  return (
    <div>
      <p>count: {count}</p>
      <button onClick={() => setCount(count => count + 1)}>Add</button>
    </div>
  )
}

function Test() {
  const [show, setShow] = useState(true)

  return (
    <div>
      <button onClick={() => setShow(show => !show)}>Toggle</button>
      {show && (
        <KeepAlive>
          <Test />
        </KeepAlive>
      )}
    </div>
  )
}

以上,将 Test 组件渲染到任意视图中,查看 KeepAlive 功能是否正常

fangzhiguo commented 4 years ago

问题解决,我今天无意中研究hooks 发现有个hooks的库安装了报的和你那个错误是一个,后来我试着把react和react-dom的版本升级到16.12.0 就好使了,这个插件不是支持16+的么,还是说官方新出的hooks造成了影响

fangzhiguo commented 4 years ago

但是现在还有个问题,这个插件兼容IE么,能兼容到10么,我试了下,反正组件报错了

CJY0208 commented 4 years ago

但是现在还有个问题,这个插件兼容IE么,能兼容到10么,我试了下,反正组件报错了

@fangzhiguo 具体是什么错呢?如果和本错误无关,需要另外开一个 issues 讨论~

TimRChen commented 2 years ago

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app

The above error occurred in the component:

Uncaught Error: Objects are not valid as a React child (found: object with keys {componentStack}). If you meant to render a collection of children, use an array instead.

index.js:1437 The above error occurred in the

component:

in h1 (at ErrorBoundary/index.js:21) in ErrorBoundary (at App.js:16) in App (at src/index.js:25) Consider adding an error boundary to your tree to customize error handling behavior. Visit https://fb.me/react-error-boundaries to learn more about error boundaries.

这些是报错内容

感谢,我也遇到了一样的问题,参考React.createElement()创建实例后解决