Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attach static methods of wrapped component to loadable component #58

Closed
artemxgruden opened this issue Apr 3, 2018 · 13 comments
Closed

Comments

@artemxgruden
Copy link

artemxgruden commented Apr 3, 2018

Attach static methods of wrapped component to loadable component

c1.mjs

import * as React from 'react'
const createElement = React.default.createElement
const Component = React.default.Component

export default class c1 extends Component {
  constructor( props ){
    super( props )
  }
  render(){
    return createElement( 'p', {}, 'hello' )
  }
  static async preloadDataState( parameters ){
    debugger
  }
}

main.mjs

import * as React from 'react'
const createElement = React.default.createElement

import * as LoadableComponents from 'loadable-components'
const loadable = LoadableComponents.default.default

import * as LoadableComponentsServer from 'loadable-components/server'
const getLoadableState = LoadableComponentsServer.default.getLoadableState

const c1 = loadable( () => import( /* webpackChunkName: "main.c1" */ './c1.mjs' ), {
  modules: [ './c1.mjs' ],
} )

const composition = createElement( c1 )

getLoadableState( composition ).then( ls => {
  console.log( c1.Component.preloadDataState )
} )

output:

[AsyncFunction: preloadDataState]

Suggestion:
attach static methods or fields directly to loadable component ( c1 ):
preloadDataState method available by c1.preloadDataState instead of c1.Component.preloadDataState

@mrasoahaingo
Copy link

Is this feature available on the latest version?

@gregberge
Copy link
Owner

Yes!

@mrasoahaingo
Copy link

mrasoahaingo commented Feb 15, 2019

Actually i can't get the statics methods of the component nor the component it self :(

Test.js

import React from 'react';

const Test = () => <h1>Test</h1>;
Test.staticMethod = () => console.log('test');

export default Test;

Main.js

import loadable from '@loadable/component';

const Test = loadable(() => import('./Test'));
console.log(Test);
console.log(Test.Component);
console.log(Test.staticMethod);

Prints

// { '$$typeof': Symbol(react.forward_ref), render: [Function], preload: [Function] }
// undefined
// undefined

@gregberge
Copy link
Owner

Methods can't be added before the module is loaded. How could we know the methods? After the component being loaded, methods will be accessible.

@mrasoahaingo
Copy link

Hum, so i need to resolve all loadable modules first before trying to access to static method?

@gregberge
Copy link
Owner

Yes.

@mrasoahaingo
Copy link

I get it now, thanks!

@windFollower29
Copy link

windFollower29 commented Feb 16, 2019

in ssr, how I can know that a loadable module has been loaded? loadableReady() must be called in browser only . @neoziro

Methods can't be added before the module is loaded. How could we know the methods? After the component being loaded, methods will be accessible.

@gregberge
Copy link
Owner

The only way to know if a component is rendered is in the component itself. The easiest method is to pass a function called when the component is mount.

import loadable from '@loadable/component';
const Test = loadable(() => import('./Test'));

<Test onLoad={() => console.log('loaded')} />
// Test.js
import React, { useEffect } from 'react'

export default function Test({ onLoad }) {
  useEffect(() => { onLoad() }, [])
  return null
}

@jsonchou
Copy link

jsonchou commented Feb 20, 2019

@neoziro

client side:

router config:

{
    path: `/index`,
    exact: true,
    page: 'Index',
    meta: {
        title: 'aaaaa'
    },
    component: loadable(props => {
        return import(/* webpackChunkName: "Index" */
        `../pages/Index/Index`)
    })
},

index page:

../pages/Index/Index

class IndexPage extends Component {
  // ...
}
IndexPage.serverApiNames = "indexApi,commonApi"  //static properties,

server side:

let currentRoute = routes[0].routes.find(router =>
    matchPath(ctx.request.path, {
        path: router.path,
        exact: router.exact
    })
)
let { exact, page, meta, component } = currentRoute

my question:

how can i get my static component.serverApiNames in server side.

@gregberge
Copy link
Owner

Loadable Components is not design to work with "statical" approach. I recommend you to use "react-navi" for this kind of approach.

@jsonchou
Copy link

thanks , i'll have a try.

@davidfurlong
Copy link

davidfurlong commented Jul 26, 2022

how can i get my static component.serverApiNames in server side.

this seems to be possible now - if you know which Loadable component is loading via a route match (react router or otherwise)

you can do

const loadedComponent = await (component as DefaultImportedComponent<any>).load();
loadedComponent?.default?.accessYourStaticPropName

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants