I am new in React Native. Right now, I am studying Props and State. I wanted to try the FlatList Component in this doc https://facebook.github.io/react-native/docs/flatlist. However, I am getting this error.
You're using typed JavaScript known as Type script.
If you want to use TypeScript (I highly encourage it, then you can do so by following below tutorial):
Migrating to TypeScript:
https://facebook.github.io/react-native/blog/2018/05/07/using-typescript-with-react-native
To just get rid of the error!
state = {selected : (new Map())};
TypeScript Migration Continued...
Adding TypeScript
The next step is to add TypeScript to your project. The following commands will:
add TypeScript to your project
add React Native TypeScript Transformer to your project
initialize an empty TypeScript config file, which we'll configure next
add an empty React Native TypeScript Transformer config file, which we'll - configure next
adds typings for React and React Native
Okay, let's go ahead and run these.
yarn add --dev typescript
yarn add --dev react-native-typescript-transformer
yarn tsc --init --pretty --jsx react
touch rn-cli.config.js
yarn add --dev #types/react #types/react-native
The tsconfig.json file contains all the settings for the TypeScript compiler. The defaults created by the command above are mostly fine, but open the file and uncomment the following line:
{
/* Search the config file for the following line and uncomment it. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
}
The rn-cli.config.js contains the settings for the React Native TypeScript Transformer. Open it and add the following:
module.exports = {
getTransformModulePath() {
return require.resolve('react-native-typescript-transformer');
},
getSourceExts() {
return ['ts', 'tsx'];
},
};
Migrating to TypeScript
Rename the generated App.js and __tests_/App.js files to App.tsx. index.js needs to use the .js extension. All new files should use the .tsx extension (or .ts if the file doesn't contain any JSX).
If you tried to run the app now, you'd get an error like object prototype may only be an object or null. This is caused by a failure to import the default export from React as well as a named export on the same line. Open App.tsx and modify the import at the top of the file:
-import React, { Component } from 'react';
+import React from 'react'
+import { Component } from 'react';
Some of this has to do with differences in how Babel and TypeScript interoperate with CommonJS modules. In the future, the two will stabilize on the same behaviour.
At this point, you should be able to run the React Native app.
Related
I have a react-native project and I'm using expo.
In my project structure I have the sources folder that contain all my sources expect the App.js file.
I would like to have this file in the sources folder as well.
For this I created a app.json file as follow:
{
"expo": {
"entryPoint": "./sources/App.js",
}
}
The issue is that when I do so after running the app with:
expo start --web
The server is launched the app is open in my browser but I have a blank screen.
There is no log, no error.
I can also add that the render method of the App.js isn't called because I put a console.log("Hello") that doesn't appear.
I don't undertstand the behaviour.
Isn't modifying the entryPoint property the way to do it ?
The expo docs state 'Support for custom entry points is in progress and is coming soon.' and suggest doing the following:
Create an index.js/index.ts file in your root folder with this content:
import { registerRootComponent } from 'expo';
import App from './src/App';
registerRootComponent(App);
where from './src/App' represents the entry location. Also delete the line
"main": "node_modules/expo/AppEntry.js",
from your package.json and any entryPoint keys in app.json or app.config.js/app.config.ts
This worked for me.
When building a Vue library (component), according to Vue docs, you can set css.extract: false in vue.config.js to avoid the users having to import the CSS manually when they import the library into an app:
vue.config.js
module.exports = {
css: {
extract: false
}
}
However, when you do that, the icons are not displayed in the production build.
In this case I'm using #mdi/font and weather-icons. Neither of them load:
To reproduce
You can reproduce this with this Vue library (component):
Create new Vue project with vue create test
Clone the repo and put in the same directory as the Vue test project
In vue-open-weather-widget set css.extract: false in vue.config.js;
And comment out CSS import:
import 'vue-open-weather-widget/dist/vue-open-weather-widget.css'
Build vue-open-weather-widget with yarn build
Import it into the test Vue app with yarn add "../vue-open-weather-widget";
Serve the test app yarn serve
I have looked at your lib (nice component BTW). I created a build with css: { extract: false } and first looked at the behavior when importing vue-open-weather-widget.umd.js directly into an HTML file. And that worked without any problems.
The thing is that the fonts remain external in the dist after the build. And it seems that there is a problem to find the fonts when your component is loaded in a Webpack project (in our case Vue CLI project). I don't know why the fonts are not referenced correctly. But I have found another, and possibly a better solution.
As it is stated in the MDI docs, the use of the web fonts can negatively affect the page performance. When importing only one icon, all of them are imported, which in turn increases the bundle size. In such a small component this is more than suboptimal, especially for the component users. Therefore here is the alternative solution, also suggested by MDI:
Use #mdi/js instead of #mdi/font
Remove all #mdi/font references in your code and install deps:
npm install #mdi/js #jamescoyle/vue-icon
Replace all icons with SVG(e.g. in MainView.vue). Note that on this way only icons are included in the bundle that are used in your components:
...
<span #click="state.settings.view = 'settings'">
<svg-icon type="mdi" :path="mdiCogOutline"></svg-icon>
</span>
...
import SvgIcon from '#jamescoyle/vue-icon'
import { mdiCogOutline } from '#mdi/js'
...
components: {
SvgIcon
},
data () {
return {
mdiCogOutline: mdiCogOutline
}
},
Adjust vue.config.js:
module.exports = {
css: {
extract: false
}
}
Build component:
# i would also include --formats umd-min
vue-cli-service build --target lib --formats umd-min --name vue-open-weather-widget src/main.js
Now your dist contains only 192.68 KiB vue-open-weather-widget.umd.min.js and the component is ready to use over CDN or in a Vue CLI Project, without importing any CSS or fonts. I have tested both cases. Here is how it looks like:
Hope it helps you! Feel free to ask if you have further questions.
I'm just getting started with react native and have created a base app with create-react-native-app.
I did some restructuring and made a few new folders and renamed the App.js to Home.js. I modified the app.json to contain an entry point that references the new Home.js file. When I load the app, nothing happens. There's no error, it just stays on the expo screen.
.
-components
-screens
-Home
Home.js
-config
-node_modules
-tests
app.json
app.json file:
{
"expo": {
"sdkVersion" : "23.0.0",
"entryPoint" : "./screens/Home/Home.js"
}
}
How do you define the entry point of the app?
if you are using Expo, you have to specify the entrypoint in your app.json file like this:
{
"expo": {
"entryPoint": "./src/app/index.js"
}
}
then, inside that file you need to register the app with Expo.registerRootComponent(YOUR_MAIN_APP_COMPONENT)
import Expo from 'expo'
...
class App extends Component {
...
}
export default Expo.registerRootComponent(App);
this way you can add your entry file wherever you want.
You need to update the app.json so that the entryPoint is the new path to the App.js.
{
"expo": {
"entryPoint": "./src/App.js",
...
}
}
However using Expo.registerRootComponent(App) causes the following error in SDK 32:
undefined is not an object (evaluating '_expo.default.registerRootComponent')
It can be fixed by importing registerRootComponent explicitly, rather than trying to access it via Expo.registerRootComponent.
Here is a sample App.js.
import { registerRootComponent } from 'expo';
class App extends React.Component {
...
}
export default registerRootComponent(App);
For Expo Projects
According to the current Expo documentation, if you want a different entry point than the App.js file, you can update the package.json - add a main field with the path to the desired entry point. Then inside the entry point file you'll have to also have to register the root component of the app. Expo was doing this automatically, when the entry point wasn't specified and was the App.js file
package.json
{
"main": "my/customEntry.js"
}
entryPointFile.js
import { registerRootComponent } from 'expo';
import MyRootComponent from './MyRoot';
registerRootComponent(MyRootComponent);
What if I want to name my main app file something other than App.js? - https://docs.expo.io/versions/latest/sdk/register-root-component/#what-if-i-want-to-name-my
If your project is in managed workflow setup (the default one), as stated in the doc, you must import the registerRootComponent and call it with your root component as argument, in the file you wish to be the main one:
import { registerRootComponent } from 'expo';
const AnyName() { ... } // Your root component
registerRootComponent(AnyName)
And then, in your package.json file, change the "main" to this file relative path, like
{
"main": "src/main.js"
}
I created project by react-native-script. In default entrypoint of app (App.js), you export App which import from your entry.
- node_modules
- App.js
- build
- main.js
File App.js:
import App from './build/main'
export default App
I also prefer to put all sources in a separated folder, for instance src/, and I found a different solution:
in my package.json, generated by expo cli, I see that main attribute is node_modules/expo/AppEntry.js.
I copied node_modules/expo/AppEntry.js to src/expoAppEntry.js and just changed the App import to import App from './App'; so it points to my *src/App.tsx`
then of course I changed the package.json main attribute to src/expoAppEntry.js.
See a working example here https://github.com/fibo/tris3d-app/blob/master/src/expoAppEntry.js
For those who are using Expo with typescript, you dont have to add .tsx at the end of the entrypoint in app.json. For example your entrypoint can be:
{
"expo": {
"entryPoint": "./app/components/AppEntryPoint/App.component",
"name": "Sample App",
...
}
...
}
In this example the name of entrypoint component is App.Component.tsx. But not mentioning the extension will also work. Apart from this, in the root component, writing export default registerRootComponent(AppComponent) or registerRootComponent(AppComponent) both should work as exporting a component from a file only means that other files can use it as well. Not writing it should not be an issue here because we have mentioned in app.json that this is the root component. App.json will look up and start building the structure of the app from there itself.
The entry point can be found in node_modules/expo/AppEntry.js..
This is in Expo Typescript...
import registerRootComponent from 'expo/build/launch/registerRootComponent';
import App from '../../src/App';
registerRootComponent(App);
In this you can change your entry point. Initially it is set to App, Look the import statement where that component is coming from.
When I load my react-native app in Expo I get the error: "Cannot find entry file index.js in any of the roots."
I am adding onto an existing React Web App, and have index.ios.js at the root level. Everything works fine locally, in simulator and through Xcode on my phone hardwired. I've converted my app with exp convert and integrated all info into exp.json.
All info for the ios app is contained in a folder called "ios".
Has anyone run into this or have any thoughts on how to get unstuck?
check you package.json and rename index.js to your entry file.
//...
},
"main": "index.js"
}
If you are using Expo, you need to go to your project folder and find the below file:
\node_modules\expo\AppEntry.js
import { KeepAwake, registerRootComponent } from 'expo';
import App from '../../App';
if (__DEV__) {
KeepAwake.activate();
}
registerRootComponent(App);
and here just replace the App to Custom_Component_Name in the second line of import.
You can find the entry file by looking in the package.json file. In package.json you will find
{
"main": "node_modules/expo/AppEntry.js"
}
AppEntry.json is the entry file by default in expo projects.
Unable to resolve module fs from /...mypath
I got this error when trying to import a node module into my react-native app.
The module used 'fs' in this way:
var fs = require('fs');
var list = JSON.parse(fs.readFileSync(__dirname + '/list.json', 'utf8'));
I ended up using 'rn-nodeify' to include fs into React Native. You can use most of the node core modules this method. Install it with npm:
npm install rn-nodeify
Then in package.json file, add the following line in "scripts" to specify which modules you want to include in your RN project. For example, I used fs, crypto and https, and the line goes
"postinstall": "node_modules/.bin/rn-nodeify --install crypto,fs,https --hack"
React Native applications do not run in the Node.js environment (it is only used by the packager to actually serve and compile your application bundle).
Since your app is running inside JS VM on either iPhone or Android, the only way to access filesystem is to use react-native-fs or any other 3rd party module that utilises bridge connection to talk to the platform specific native APIs.
it took me a while to find the issue, I'm sharing it as it might be useful for future reference (using react native with Expo):
One of my coworkers accidentally imported in one of our react components app.config.js in the project root to read some configuration rather than using expo-constants.
it was causing it to read the .env file from the react native wrapper that obviously doesn't have the fs lib.. this is the first line of our app.config.js:
import 'dotenv/config';
the correct way for reading settings inside app.config is:
import Constants from 'expo-constants';
const appConfig = Constants.manifest;
Install react-native-fs (follow the instructions at de link), so weather the error persist, enter at the directory ('./node_modules/tfjs-image-recognition-base/build/commonjs/env/) search by the file: (creatFileSystem.js) and edit:
fs = require('fs')
to:
fs = require('react-native-fs')
I don't know if this is recommended way, but was the only that worked for me.
If you want to import a json list just call it direct.
Example:
import subscriptionData from './assets/dataSource/subscriptionData.json';
or
var subscriptionData = require('./assets/dataSource/subscriptionData.json');
You don't need to convert it, and you can use to import your data or the way you want.
function installJson() {
console.log("Iniciando Importação");
subscriptionData.forEach(item => {
firestore().collection('subscription').add(item);
});
}
subscriptionData.json
[{
"code": 325,
"name": "bla bla bla"
},
{
"code": 356,
"name": "ble ble ble"
}]
Instead of:
const fs = require('fs');
Try:
const fs = require('react-native-fs');
worked in my case.