I have successfully installed react-native-i18n and its works fine. However, I want to change the locale inside the React native app itself.
I have added a button( Touchable opacity ) and have written the following code :
onPress={() => { i18n.locale = 'ar'; }}
However, this does not change the locale to 'ar' and all my translations are still coming for english ( en-US ) only. I dont want the user to go to phone settings and change the locale from there. Can I not do it from the app itself? Only so that the locale is limited for my app only.
You need to rerender the app. Listen for ConfigurationChange event to rerender or you may refer this GitHub issue. Easier hack is to set a state once you do i18n.locale = 'ar' :)
Related
I have read in the Expo/RN documentation, that for getting the system color (dark/light) we should use this API from react native.
So, I have decided to create my custom hook
import { Appearance } from "react-native";
export default function useIsDarkModeEnabled() {
return Appearance.getColorScheme() === "dark";
}
But for some reason, it is always returning me false. I am testing on iOS 14, with dark theme enabled.
Any ideas?
Whenever I check the current appearance of the device I use the useColorScheme() function, not getColorScheme().
You can use Context to persist it throughout the application, or put it at the root of your app and pass it down to your components as props (not the best). To persist the theme, you can use AsyncStorage to store the last state of the appearance.
Then whenever the application opens, it will pull that last state unless the device has changed its appearance since then.
I come from a React background, but I'm switching to Svelte and Sapper for my next application in order to fight the massive bundle size that comes with React these days. However, I'm having trouble initializing Svelte's store with data retrieved from localStorage.
As per the Sapper docs (https://sapper.svelte.dev/docs#Getting_started), I created my project by running npx degit "sveltejs/sapper-template#rollup" my-app from the command line. I then installed the dependencies and removed the demo code in the src folder.
I then created two files: src/routes/index.svelte and src/store/index.js.
Code for both:
src/store/index.js
import {writable} from "svelte/store";
export let userLang;
if(typeof window !== "undefined") {
userLang = writable(localStorage.getItem("lang") || "en");
} else {
userLang = writable(null);
}
src/routes/index.svelte
<script>
import {userLang} from "../store";
</script>
<p>Your Preferred Language: {$userLang}</p>
When I run the application and hit the index route, I see this:
Your Preferred Language: null
which then almost immediately updates and changes to
Your Preferred Language: en
when there is no lang item in localStorage, and changes to
Your Preferred Language: fr
After explicitly setting localStorage.setItem("lang", "fr") from the developer console and refreshing.
I know that the store is being initialized on the server first where window is undefined and then is being rehydrated on the client. So this behavior is expected.
So my question is: how can I skip the server initialization entirely? Is it possible to only set up the store on the client (where localStorage is defined) so that the user's chosen language is immediately available?
I can't default to having everything in English or any other language after the user has chosen to change their preferred language. I also can't get the user language from the browser via navigator.language on initial page load either since navigator is undefined on the server as well.
And having a flash of empty text appear before the store rehydrates would screw up the UX for my application, especially when the value of userLang is going to be used all over the place with translations.
So any strategies or hacks for this are definitely appreciated.
**** Deeper Issue ****
I would actually prefer to not have server-side rendering at all for this application, but I do need all the other excellent features that Sapper provides, like routing, prefetching, and static site building.
So I tried running npx sapper export as per the docs to generate a completely static site in an effort to remove the server from the equation, but the exact same issue still occurs, even though there is no server being used at all.
Does anyone have any advice on how to configure Sapper and turn off SSR but keep the other features?
Thank you!
**** Update ****
As per Rich Harris's answer, wrapping the markup with {#if process.browser} does the trick just fine. So I've updated the src/routes/index.sveltefile like so:
<script>
import {userLang} from "../store";
</script>
{#if process.browser}
<p>Your Preferred Language: {$userLang}</p>
{/if}
And the userLang variable is immediately set with the value from localStorage or defaults to en as I intended for this simple demo. There is no more flash of null, so it's essentially behaving like it's client-side only at this point.
I will work on fleshing out my project and see if there are any more issues I encounter. Til then, I think this solves my issue.
At present, SSR is non-optional. There's an issue open for an SPA mode — https://github.com/sveltejs/sapper/issues/383 — that would behave as you describe, we just need to get round to it.
We also plan to have built-in support for i18n in a future release: https://github.com/sveltejs/sapper/issues/576
In the meantime, you can fake it by wrapping all your markup in {#if process.browser} — anything inside won't be server rendered, but will be present as soon as JavaScript kicks in.
I've got a very simple hook that looks like this:
export const QuickViewCell = props => {
const [hover, setHover] = useState(false)
const handleMouseEvent = () => {
console.log('calling')
setHover(!hover)
}
console.log('hoverState', hover)
return (
<Box onMouseEnter={handleMouseEvent} onMouseLeave={handleMouseEvent}>
<Text size="small">
{String(props.data.name)} this is my custom cell and it is amazing
</Text>
</Box>
)
It works when placed in one part of the project, but doesn't when placed in another. Meaning, the handleMouseEvent function is always being called, but the component isn't re-rendering with the new state. React and React-Dom are at 16.8.1. I'm not getting any errors. I'm not sure where to look for the bug.
If I change it to a class component using setState, it works fine, which makes me think I've got an incompatibility issue somewhere, but without an error message, not sure where to look. Or I'm missing something more obvious :)
Anyone experience something like this? Is there a way to determine if there is an incompatibility with another package?
Based on the following wording in your question:
It works when placed in one part of the project, but doesn't when
placed in another.
I assumed that the two places were part of the same build (i.e. same package.json). If that was the case, it seemed unlikely that it was an incompatibility issue. But the following recent comment:
The code for this component is identical in both cases, it's mainly
the packages that are different.
makes it sound like the two cases are part of separate builds. If this is true, then I think the hook-incompatibility theory is reasonable, though I'm not entirely convinced because I would expect a message in the console in that case (but I suspect there are some variations on the multiple-react-copies issue that wouldn't cause a message in the console).
The following page from the documentation has instructions on troubleshooting this:
https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react
On that page you'll find the below instructions for determining whether you have multiple versions of react in play.
You can run npm ls react-dom or npm ls react-native in your
application folder to check which version you’re using. If you find
more than one of them, this might also create problems (more on that
below).
And then further down:
If you use Node for package management, you can run this check in your
project folder:
npm ls react
If this doesn't show any surprises (i.e. just shows one copy of 16.8.1 for both react and react-dom), then I would move forward with assuming there is something other than an incompatibility going on and would want to see the code that uses QuickViewCell in the problem case.
On a tangential note regarding jayarjo's recommendation to use the "functional update" syntax, I think the more appropriate way to update this hover state in order to more easily know that it is correct/robust would be to explicitly pass the boolean rather than doing a toggle of whatever the state currently is.
For example:
export const QuickViewCell = props => {
const [hover, setHover] = useState(false)
return (
<Box onMouseEnter={()=>setHover(true)} onMouseLeave={()=>setHover(false)}>
<Text size="small">
{String(props.data.name)} this is my custom cell and it is amazing
</Text>
</Box>
);
}
This makes it easier to be confident that you won't accidentally get in a state where hover is stuck as the opposite of what it should be.
When previous state is used to calculated next one, it is recommended to use functional updates.
So instead of setHover(!hover) try setHover(hover => !hover). That should do.
I am building a new project using angularjs and PHP(codeigniter).
I am facing an issue with the content or changes I make on both client-and serverside, but the changes are not being reflected.
Does this have something to do with the cache?
The browser uses template caching, which should be cleared upon making changes to templates. See this question. You can do the following to make your life easier when developing:
Reload the page with clearing cache each time you need to update your app
Yet a more convenient way is to:
Disable cache in developer tools
E.g. for Chrome
CTRL+SHIF+J and on the network tab check 'Disable Cache'
Yet may be better still to:
Remove template cache in your application
This is done via $templateCache.remove()
More info on preventing template caching
Try this if you are also having issue with Angular default change detection mechanism. In my case, in my ionic4 Project default change mechanism of Angular was somewhat not working properly so I triggered it manually.
constructor(private ref: ChangeDetectorRef) {
ref.detach();
setInterval(() => {
this.ref.detectChanges();
}, 500);
}
I am integrating I18n-js in a Rails application. The integration is working fine along with the translations.But the problem I am facing is that when the required translation is not present in a particular language , say for example I selected Afrikaans as my language then in that case the fallback method should execute showing me the translation present in the default language.But its not happening and I get the error
[missing "af.credential_requests.add" translation]
This surely means that the fallbacks method is not working.
Though I have
I18n.fallbacks = true;
in my I18n-js. Please help.
I have my default locale set to "en"
Make sure that you set I18n.defaultLocale correctly