React Native Storybooks Component not Loading - react-native

I'm trying to load the default stories that come when you first install Storybook. Had some issues getting the server to start but I managed to fix it by adding port and host in the config. But even after getting it to run, clicking on any of the components doesn't update.
I'm expecting to see a Button.
And ideas? Here's the storybook index.js. I'm using Expo.
// if you use expo remove this line
// import { AppRegistry } from "react-native";
import {
getStorybookUI,
configure,
addDecorator,
} from "#storybook/react-native";
// import { withKnobs } from '#storybook/addon-knobs';
import "./rn-addons";
// enables knobs for all stories
// addDecorator(withKnobs);
// import stories
configure(() => {
require("./stories");
}, module);
const StorybookUIRoot = getStorybookUI({
host: "192.168.100.6", // replace this ip address with your local ip address
port: "7007",
asyncStorage: null,
});
// If you are using React Native vanilla and after installation you don't see your app name here, write it manually.
// If you use Expo you should remove this line.
// AppRegistry.registerComponent("%APP_NAME%", () => StorybookUIRoot);
export default StorybookUIRoot;
Also not sure if this is related but I've had to comment out addon-knobs in addons.js because it can't find it even though I have addon-knobs in my package.json:
import '#storybook/addon-actions/manager';
import '#storybook/addon-links/manager';
// import '#storybook/addon-knobs/manager';
I've tried replacing it with
register
like I've read on here but it still didn't work.
import '#storybook/addon-knobs/register';

Related

Missing keys issue in i18next with only one React Component

I am developing a react-project with multilingual (en and fr). Everything is working fine and I am able to translate my app from en to fr and vice versa. The translations are working when refreshing the page too.
I have one React Component that is unable to translate and is showing a missing key error.
i18next::translator: missingKey fr translation CampaignDetails.description CampaignDetails.description
Instead of translating the text for description, it is showing me CampaignDetails.description exactly
PROBLEM EXPLANATION
Go to this URL http://donatenow-9cc92.web.app/
Try changing the language at the rightside of the header. It will work.
There is a search field at the leftside in the header. Search for "mervice" and wait until the
charity shows up
You can see a card for the searched charity, click on the card anywhere but not on follow
button
The URL now looks like this https://donatenow-9cc92.web.app/mervice
Try changing the language now and it will work too.
Refresh this page https://donatenow-9cc92.web.app/mervice and you will see the translations
are still working
Now scroll this page https://donatenow-9cc92.web.app/mervice and at the bottom, you will see
some campaigns like 'Sadqah', 'Zakat' and 'Dollar a Day for Sadaqa'. Click on any campaign,
lets say you have clicked 'Sadqah'
Now the URL is something like this https://donatenow-9cc92.web.app/mervice/sadqah
Try changing the language from this route and it will work fine
The problem is if you click on this link https://donatenow-9cc92.web.app/mervice/sadqah
directly or refresh the page. The translation will not work and the console will give you
missing keys error
EXPLANATION TO POINT 11
1- I have a NotFound.js component in which I am checking if the URL has any charity name like mervice. For example, if the URL is like this domainName/mervice then I am extracting the mervice from the URL and doing a Axios call to fetch the charity and then navigating to the charity page
https://donatenow-9cc92.web.app/mervice (The translations are working no matter if the user has come directly to the page or He/She searched for the charity)
2- In the same function of NotFound.js in which I am fetching the charity, I am also fetching the campaign for the charity. I am checking if the URL is like this domaninName/mervice/campaign and then if the campaign is found for the charity (mervice in this case) then I am navigating to the campaign page.
3- https://donatenow-9cc92.web.app/mervice/sadqah (The translation will not work if you click on this link directly but translations will work if you do it manually like using the search field)
If the translation is working for this page https://donatenow-9cc92.web.app/mervice then why it is not working for this page https://donatenow-9cc92.web.app/mervice/sadqah
The component is the same, I am only navigating in this component based on the condition
Index.js
import React, { Suspense } from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import "./css/Auth.css";
import "./css/SearchOrganization.css";
import "./css/Profile.css";
import "./css/Donations.css";
import "./css/ReceiptModal.css";
import "./css/Recurring.css";
import { Provider } from "react-redux";
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import HttpApi from "i18next-http-backend";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import store from "./redux/store";
const root = ReactDOM.createRoot(document.getElementById("root"));
i18n
.use(initReactI18next)
.use(LanguageDetector)
.use(HttpApi)
.init({
debug: true,
supportedLngs: ["en", "fr"],
fallbackLng: "en",
detection: {
order: ["localStorage"],
caches: ["localStorage"],
},
backend: {
loadPath: "assets/locales/{{lng}}/translation.json",
},
interpolation: {
escapeValue: false,
},
});
root.render(
<Suspense fallback={null}>
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
</Suspense>
);
reportWebVitals();
NotFound.js
axios
.get(`${hostName}api/v1/search/organization?name=${lowercase}&type=shortName`)
.then((res) => {
if (res.data.data.length > 0) {
// setting states
setLoader(false);
setError("");
// local storage
localStorage.setItem("organization", JSON.stringify(res.data.data[0]));
// setting props
setOrganizationDetails(res.data.data[0]);
// setting organization path
const data = res.data.data[0];
const organizationName = data.shortName;
const cleanOrganizationName = organizationName.replace(
/[^a-zA-Z0-9]/g,
""
);
setOrganizationPath(cleanOrganizationName.toLowerCase()); // redirects to charity translation is working
// fetching campaign for the given organization
for (let i = 0; i < data.campaigns.length; i += 1) {
const word = data.campaigns[i].name.replace(/[^a-zA-Z0-9]/g, "");
const lowercase = word.toLowerCase();
if (secondString === lowercase) {
setCharityPath(lowercase); // redirects to campaign, translation not working
setCharityDetails(data.campaigns[i]);
localStorage.setItem("campaign", JSON.stringify(data.campaigns[i]));
break;
} else {
setCharityPath(null);
setCharityDetails(null);
localStorage.removeItem("campaign");
}
}
}
});

Cannot run expo web

I encounter the error 'Cannot access __fbBatchedBridgeConfig on web' when trying to run expo web
The instructions I got according to https://github.com/expo/fyi/blob/main/fb-batched-bridge-config-web.md was to do the following
Remove internal imports
You can remove the import altogether, or you can move an internal import inside of a platform specific block:
import getDevServer from "react-native/Libraries/Core/Devtools/getDevServer";
or
let getDevServer = () => { /* no-op */ }
if (Platform.OS !== 'web') {
getDevServer = require("react-native/Libraries/Core/Devtools/getDevServer");
+ }
However, I'm not sure where to insert this code. I've tried inserting it on my home page, on app.js, and I still encounter this error.
Could anyone help me out on this?
(I'm using EXPO 4.13.0, SDK 43 and react-native 0.64.3)
This error shows when you try to use a nested library from react-native.
Search specifically for react-native/ with your IDE in your project to find where you are importing such nested library.
There you can replace the offending import like:
import example from "react-native/example";
to:
let example = () => { /* no-op */ }
if (Platform.OS !== 'web') {
example= require("react-native/example");
}
You also need to import Platform like:
import { Platform } from 'react-native';
But note other errors might arise if you DO need to use that library, so also edit where you are using it.

No connection reactotron / react-native

I try to debug an application with Reactotron in a (IOS) React Native project but there is "No Activity" when I run my application.
I work with react-native 0.55.4, reactotron 2.1.0 (same in my package.json)
TimeLine Reactotron
My reactotronConfig.js
index.js file where reactotron is imported
reactotron in my package.json
You have to do the following:
enter on CLI: adb reverse tcp:9090 tcp:9090
add this to a file (e.g lib/Reactotron.js):
import Reactotron, { asyncStorage } from 'reactotron-react-native';
Reactotron
.configure() // controls connection & communication settings
.useReactNative(asyncStorage()) // add all built-in react native plugins
.connect();
import the File in your app.js:
if (__DEV__) {
import('../../lib/Reactotron').then(() => console.log('Reactotron Configured'));
}
Note: If you wan't to use host Prorperty inside of configure(), be sure to use 127.0.0.1. In my case other IP (even if local like 192.x.x.x) doesn't work.
After that, you connection should work, and you can use Reactotron like described in the Docs.
HINT:
For Linux & Mac, you can add this to package.json (script-section) (adjust the path & call of your reactotron-app to your needs):
"scripts": {
...
"reactotron": "adb reverse tcp:9090 tcp:9090 && /opt/Reactotron/reactotron-app",
...
}
I did this adb reverse tcp:9090 tcp:9090 that I got from Suther and yarn start --reset-cache and it worked.
First of, you are not assigning the configured Reactotron object to your console.tron value. You need to do something like this:
console.tron = Reactotron.configure({ ...
Looking at your reactotronConfig.js file I notice that you are sending it to localhost. This will only work when running on the simulator (not sure if that is what you are doing).
If you want to run it on a device, you will need to give it your packager's ip address. A neat way of doing that is to use the following code:
import { NativeModules } from 'react-native';
let packagerHostname = "localhost";
if (__DEV__) {
const scriptURL = NativeModules.SourceCode.scriptURL;
packagerHostname = scriptURL.split("://")[1].split(":")[0];
}
const reactotron = Reactotron.configure({
name: "myAPPILOC",
host: packagerHostname
});
console.tron = Reactotron;
Please enable debug mode ( Press ⌘+D on iOS simulator, ⌘+M on Android emulator, or shake real devices). Then kill app and restart app.
I hope it's help
What I can recommend and what has worked for me is to install these version packages:
"reactotron-react-native": "3.5.0",
"reactotron-redux": "3.1.0",
Then you will need to configure your store accordingly:
import {createStore, applyMiddleware, compose, combineReducers} from 'redux';
const appReducer = combineReducers({
...reducers,
});
const middleware = applyMiddleware(thunkMiddleware);
//react-native-debugger config
// eslint-disable-next-line no-underscore-dangle
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
// const store = Reactotron.createStore(appReducer, composeEnhancers(middleware));
const store = createStore(appReducer, composeEnhancers(middleware, Reactotron.createEnhancer()));
Now of course, the above is my setup but you will need to tweak yours accordingly, the main point being follow the Configuration as documented here:
https://github.com/infinitered/reactotron/blob/master/docs/plugin-redux.md

use redux-devtools-extension with react-native with chrome

Need help in setup Redux devTools for react-native
I have very simple reducer and createStore here, and I try to incorporate redux-devtools-extension, so I can debug my react-native
app, but I got "store no found" in Redux tab
import { createStore, applyMiddleware} from 'redux'
import {reducer} from "./reducers"
import { composeWithDevTools, devToolsEnhancer } from 'redux-devtools-
extension'
let store = createStore(reducer, devToolsEnhancer());
export const reducer = (state=[], action) => {
switch(action.type) {
case "ADD_MEMBER":
return [...state, {categoryID: 0, name: "Bill", zip: "27733", id: 4}]
default:
return state
}
return state;
}
Redux DevTools Extension cannot access the React Native worker, as extensions cannot inject code into web workers. You have to use remote-redux-devtools to communicate with the extension via websockets.
You'll have just to replace
import { devToolsEnhancer } from 'redux-devtools-extension'
with
import devToolsEnhancer from 'remote-redux-devtools';
Then from the extension context menu, click on "Open Remote DevTools". By default it'll use its remote server for quick bootstrapping, but it's recommended to run your local server by installing and running remotedev-server. It's similar to how you have to install and run react-devtools package for React Native.
Another option is to use React Native Debugger.
The win is, you don't have to npm install redux devtools every time. The debugger provides you the good old "REDUX_DEVTOOLS_EXTENSION" out of the box.
So, if you are reusing code from web, you do not need any code changes. The same set up as redux devtools extension will just work.
For a thorough guide on how to setup React Native Debugger with an Expo app look here. (As the official docs are a bit confusing.)

How do I render a Shoutem extension

I was wondering how I would render some Shoutem extension, for simplicity I am going to render it as my only component like so:
import 'es6-symbol/implement';
import React from 'react';
import {
AppRegistry,
View
} from 'react-native';
import { AppBuilder } from '#shoutem/core';
import { NavigationBar } from '#shoutem/ui';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import extensions from './extensions.js';
import { screens } from './extensions/kevinyclu.restaurants/app/index';
const List = screens.List;
const store = createStore((state, action) => state);
const App = () => <Provider store={store}><View><List /></View></ Provider>;
// noinspection JSCheckFunctionSignatures
AppRegistry.registerComponent('Restaurant', () => App);
But this gives me an error that says:
Though if I replace the const App = ... with the code that was initially there when I did shoutem configure
const App = new AppBuilder()
.setExtensions(extensions)
.setRenderNavigationBar(renderNavigationBar)
.build();
Then everything works fine, so I was wondering how would I use a Shoutem extension? Or am I missing the point of the extension completely?
You simply add it in the Builder by adding a screen. The flow is explained in our getting started docs. You create an extension, create a screen with a shortcut and then upload it to the Shoutem servers and install it in one of your apps on the Builder.
After that, you can go to the app in the Builder and add that new extension's screen by clicking the + button next to Screens. You can easily find your new extension by selecting the Custom category.
Remember that after installing a new app, you should run shoutem configure in the cloned app's directory. This will set up the new configuration you have after you've installed a new extension on the Builder.
Some advice; if you ever uninstall an extension on the Builder, it's good to re-clone your app completely, because shoutem configure will not remove the extension's from the directory, which may "hide" errors. For example, you could be importing something from that extension that you uninstalled, but you won't get an error because the files are all still there, even though they're uninstalled.