0

Is it possible to live reload react-intl messages during development(for default language)?

I mean like Hot Module Loading, only updated message should be affected. Any ohter solution without running extra script or refreshing whole page will work too.

Thank you.

Mohamed
  • 1,251
  • 3
  • 15
  • 36

2 Answers2

3

In case anybody need it, I wrote HOC for this;

import React, {Component} from "react";
import {IntlProvider} from "react-intl";

const url = location.protocol + '//' + location.host + "/";

class IntlLoader extends Component {
    constructor(props) {
        super(props);
        const {initialLocale: locale, initialMessages: messages} = props;
        this.state = {locale: 'en', messages};
    }

    fetchLanguagesForDevelopment = () => {
        // if development, use hot loading
        if (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') {
            this.setState({...this.state, loading: true})
            fetch(url + "reactIntlMessages.json")
                .then((res) => {
                    return res.json();
                })
                .then((messages) => {
                    this.setState({loading: false})
                    if (messages !== this.state.messages)
                        this.setState({...this.state, messages})
                })
                .catch((error) => {
                    this.setState({error, loading: false})
                })
        } else {
            const messages = require('../../dist/reactIntlMessages.json')
            if (this.state.messages !== messages)
                this.setState({...this.state, messages, loading: false})
        }
    }

    componentDidMount() {
        this.fetchLanguagesForDevelopment()
    }


    componentWillReceiveProps(nextProps) {
        this.fetchLanguagesForDevelopment()
    }

    render() {
        const {error, messages, loading} = this.state;
        //if (loading) return (<div>Please wait...</div>)
        if (error) return (<div>Error While Loading Language</div>)

        return (
            <IntlProvider {...this.state}>
                {this.props.children}
            </IntlProvider>
        );
    }
}

export default IntlLoader
Mohamed
  • 1,251
  • 3
  • 15
  • 36
1

You can module.hot.accept your translated messages and render it as argument. See this example in react-boilerplate

https://github.com/react-boilerplate/react-boilerplate/blob/v3.5.0/app/app.js

const render = (messages) => {
  ReactDOM.render(
    <Provider store={store}>
      <LanguageProvider messages={messages}>
        <ConnectedRouter history={history}>
          <App />
        </ConnectedRouter>
      </LanguageProvider>
    </Provider>,
    MOUNT_NODE
  );
};

if (module.hot) {
  // Hot reloadable React components and translation json files
  // modules.hot.accept does not accept dynamic dependencies,
  // have to be constants at compile-time
  module.hot.accept(['./i18n', 'containers/App'], () => {
    ReactDOM.unmountComponentAtNode(MOUNT_NODE);
    render(translationMessages);
  });
}
Alv 黄將雄
  • 43
  • 2
  • 7