Conditional import or alternative in JavaScript (ReactJS WebApp)?

后端 未结 3 1197
猫巷女王i
猫巷女王i 2021-01-19 09:28

I\'m implementing internationalization for a ReactJS webapp. How can I avoid loading all language files?

import ru from \'./ru\';
import en from \'./en\';

         


        
相关标签:
3条回答
  • 2021-01-19 10:18

    Take a look at the react-loadable package - if you can somehow encapsulate your language files into components, this might solve your problem.

    0 讨论(0)
  • 2021-01-19 10:20

    Unfortunately there is no way to dynamically load modules in ES6.

    There is an upcoming HTML Loader Spec which will allow for this functionality, so you could use a polyfill in order to use that.

    const chooseLang = () => System.import(`./${language}`);
    export default chooseLang;
    

    However, this would now be promise-based so it would need to be called like so:

    import language from "./language";
    language.chooseLang().then(l => {
        console.log(l);
    });
    

    But bear in mind, that spec could change radically (or be dropped altogether).

    Another alternative would be to not store your localizations as Javascript modules, but as JSON instead, e.g.

    en.json

    { "hello_string": "Hi!" }
    

    language.js

    const chooseLang = () => {
        return fetch(`./${language}.json`)
            .then(response => response.json());
    };
    

    Again, this would be promise based so would need to be accessed as such:

    import language from "./language";
    language.chooseLang().then(l => {
        console.log(l.hello_string);
    });
    

    That solution would be fully ES6-compliant and would not rely on possible future features.

    0 讨论(0)
  • 2021-01-19 10:26

    Looks like I am late here, but I would like to answer the approach I am using. I have an async component:

    import React from 'react';
    
    export default (loader, collection) => (
      class AsyncComponent extends React.Component {
        constructor(props) {
          super(props);
          this.Component = null;
          this.state = { Component: AsyncComponent.Component };
        }
    
        componentWillMount() {
          if (!this.state.Component) {
            loader().then((Component) => {
              AsyncComponent.Component = Component;
              this.setState({ Component });
    
            });
          }
        }
    
        render() {
          if (this.state.Component) {
            return (
              <this.state.Component { ...this.props } { ...collection } />
            )
          }
    
          return null;
        }
      }
    );
    

    And we call it using:

    const page1 = asyncComponent(() => import('./page1')
      .then(module => module.default), { name: 'page1' });
    

    and then we use it with:

      <Route path='/page1' component= {page1}/>
    

    This will ensure that loading is done dynamically.

    0 讨论(0)
提交回复
热议问题