synacor / preact-i18n

Simple localization for Preact.
BSD 3-Clause "New" or "Revised" License
205 stars 18 forks source link

Get text from definition without Components #23

Closed tzvc closed 6 years ago

tzvc commented 6 years ago

Hi,

Is there a way to access the definition object from the IntlProvider for getting text directly without using a Component ?

Thanks ❤️

billneff79 commented 6 years ago

You can access the definition anyplace where you can access context, which is just about any place inside of a component where the this scope is the component. context is also the second argument, after props to a pure functional component.

The definition is placed currently in context.intl.definition, however since that isn't part of the official API of this package, that is subject to change and you are safer using something like the withText function to get text out of the definitions and into props.

If you are trying to get the definitions to something like a utility library, you ultimately have to get the definitions from a component/pure functional component and either pass those in as arguments to the utility function, or store the values in some value that the utility library can read later.

For example

Component

import { setDefinitions } from './utils';

@withText('a, b');
class Foo extends Component {

    componentWillMount() {
        setDefinitions({a: this.props.a, b: this.props.b});
    }

    componentWillReceiveProps({a, b}) {
        //Might want to do performance comparison for your use case of always setting vs. doing comparisons before setting
        if(this.props.a !== a || this.props.b !== b) setDefinitions({a, b});
    }
}

Library Functions

//to be used in utility functions, but defined by setter used in a component
let definitions;

export function setDefinitions(d) { 
    definitions = d; 
}

//This is a function that assumes definitions have been set.  This is necessary if calling from 
//another utility function or from a component that doesn't have access to the definitions
export function impliedDefinitionsFunction() {
    if(!definitions) throw new Error("Definitions need to be defined before calling this utility function");
    //Do something with definitions here
}

//This is a function that assumes definitions are passed.  This is preferred if calling from a component
export function explicitDefinitionsFunction(defs) {
    //use the passed in definitions to do something
}