Importing Google Maps API JS file with React - reactjs

I'm trying to integrate the polygon containsLocation function into my react app. This currently appears to only be supported by the actual JS library imported with the maps.googleapis.com script tag added. That being said, I keep getting the no-undef error when attempting to use the maps.Polygon constructor (I'm currently using create-react-app with the default settings). Is there anyway to prevent this from happening?
Code causing the issue:
var addedPoly = {
polygon: maps.Polygon({
paths: parsedCoords
})
}

create-react-app uses Eslint in order to lint your code. Given you've included the google maps library through a script tag, it is available globally, while create-react-app (with its eslint configuration) doesn't expect globals, unless they are declared as such.
You can see in eslint documentation the no-undef error
There are a couple of choices to fix this issue. First, if it is global, it will be available through window variable.
const maps = window.maps;
That way, it becomes a local variable.
Otherwise, you could add a .eslintrc file (if it does not exist already), where you set maps as global
"globals": {
"maps": true
}
last, but not least, you could add at the top of your file the following comment
/*global maps*/
which will also work.
The advantage of the second option over the others is that you only need to implement it once, the other two options imply changes in each file where maps is used. It is up to you

Related

For more clarification about react components [duplicate]

I would like to understand the technical difference between them so as to determine the appropriate one to use.
I've realised that they can both have same content and sometimes used interchangeably in some projects.
How does .jsx files differ from .js?
Update for Newer Users
The JSX Compiler tool has been removed as JSXTransformer has been deprecated. The React Team recommends using another tool such as the Babel REPL.
If you wish to keep the JSX source code intact for better maintainability, I would keep them as .jsx files. Using the JSX Compiler, either manually or via build script, will convert your JSX syntax to normal JavaScript files.
Note: It is possible to serve JSX files in your production environment but React will give you console notices about reduced performance.
Personally, I would use something like gulp-jsx or gulp-reactify to convert the files.
Example with gulp-jsx:
var gulp = require('gulp');
var jsx = require('gulp-jsx');
gulp.task('build', function() {
return gulp.src('path/to/*.jsx')
.pipe(jsx())
.pipe(gulp.dest('dist'));
});
Checkout this discussion:
ReactJS - .JS vs .JSX
JSX is neither JS nor HTML, so giving it its extension helps indicate what it is. You can find some more discussions and docs linked there.

What is the correct way to include React in both an application and a private library? (React Invalid Hook Call warning from duplicate React)

I have a sort of a "monorepo", one big project consisting of a few smaller projects that use React.
I'm trying to break these up into three separate repositories, lets call them Core, Application1, and Application2
The Core is a dependency of both applications, and the Core depends on React, because it defines some React component classes. The applications both also use React.
When I tried to build this all together (using Parcel bundler), I am getting a final bundle which at runtime gives the Invalid Hook Call warning in one (but not both) of the applications.
On that page (or in the error message), it says that the error could be caused by one o these:
You might have mismatching versions of React and React DOM.
You might be breaking the Rules of Hooks.
You might have more than one copy of React in the same app.
I have checked that #1 is not true, and I'm not even using hooks in any way that I am aware of, so the problem is seems to be multiple versions of React.
I gathered from reading about this that it was a mistake for my Core library to declare React as a dependency, and that it should instead declare it in peerDependencies. That made the Application stop giving the error, but it also made my Core library start having a bunch of Typescript errors and failing to be able to run the unit tests (which rely on React, using Jest/Enzyme to render and validate DOM).
Since specifying React in peerDependencies caused it not to be installed in the node_modules of Core, I decided that I should probably include React in both the peerDependencies and the devDependencies of Core. That fixes the Core library again but breaks the Application.
I'm not really sure of the following:
Why one of my applications fail due to duplicate React copies and the other doesn't, since they seem pretty symmetrical to each other.
Why, even though I only specify React in peerDependencies and devDepenencies in Core I still would get a duplicate copy of React in the dependent application
Whether the method used to bring Core in to the application has any bearing on this. (one method I'm trying is package.json I specify core as a "file:../" style of URL. Another alternative is to use "yarn link", or possibly to do both of these, and I'm not sure whether this has any effect on what ends up in node_modules underneath the application folder or on what gets bundled)
What is the right way to include React in both an Application and a library, in such a way that both of those projects have React available but there does not end up being duplicates in the Application causing this hook error (or, just taking up extra space).
Answering my own question.
I found the following issue helpful: https://github.com/facebook/react/issues/14257
Various different suggestions were made in the comments of ways to solve this problem, either by npm link or yarn linking the react library from the library to the application, or vice versa. Those all seemed promising, since the idea is to make sure that all of the different references to React are actually pointing to the same place. Unfortunately none of those worked for me. (e.g. the answers by JerryGreen and Kas in that issue)
Another user, dcecile, suggested using webpack's alias feature, but I'm not using webpack.
resolve: {
alias: { react: require.resolve("react") }
},
Parcel has a similar alias feature but can't be used in quite the same way because it's used in the package.json file so things like require.resolve can't be called like they are in webpack's js config file.
I ended up finding a way to use Parcel's alias feature to do what I wanted, based on another example from https://github.com/jaredpalmer/tsdx/issues/64 from user jaredpalmer. In my situation, I'm adding this to the application's package.json, and it appears to get rid of the duplication problem and the "Invalid Hook Call" error:
"alias": {
"react": "../my-core-library/node_modules/react",
},

Gatsby, Environment variables not accessible in browser

I want to use environment variables. I created .env.development file and I put some variables. Then I include the dotenv plugin to read the variables in gatsby-config.js:
require('dotenv').config({
path: `.env.${process.env.NODE_ENV}`
});
The content of my .env.development:
GATSBY_APP=MYAPP
It's working in gatbsy-node.js but in browser (REACT) it's empty. I display console.log(process.env) and it return empty object.
Even if I install and configure gatsby-plugin-env-variables.
It looks like you're combining two approaches, and that might be where you're running into trouble.
Gatsby comes out-of-the-box with support for defining environment variables in environment-specific .env.[environment] files (e.g. .env.development), provided these files are in the root of your project (i.e. your-project/.env.development). Documentation for this feature. You do not need to install or configure dotenv for this to work.
Another approach is to use dotenv, which will allows you to use a general .env file. You need to then import and configure the tool, which is generally done at the very top line of gatsby-config.js and looks like this:
require("dotenv").config()
Note that you do not specify the environment name (e.g. development) in this scenario, and you would not commit the .env file to your repository.
The other issue you might run into is that part of your code runs server-side, using Node, and part runs client-side (in the browser). Since process.env is only available in Node, Gatsby does some additional work to make it available in the browser. We don't want all of these variables, which frequently hold secrets, to be provided to the browser, though, so Gatsby only copies over those that whose names begin with GATSBY_. Finally, as a side effect of the way that these variables get copied over, you must explicitly reference them for your build to work:
// this is okay everywhere
const GATSBY_APP = process.env.GATSBY_APP
// this won't work in code that runs client-side, but will work
// in `gatsby-node.js` and other files that only run in Node
const { GATSBY_APP } = process.env
If you wanted to whitelist your own environment variables, either as a prefix (shown here) or have a list of them, you can add something like this in the gatsby-node.js file:
exports.onCreateWebpackConfig = ({ actions, getConfig }) => {
const config = getConfig();
// Allow process.env.MY_WHITELIST_PREFIX_* environment variables
const definePlugin = config.plugins.find(p => p.definitions);
for (const [k, v] of Object.entries(process.env)) {
if (k.startsWith("MY_WHITELIST_PREFIX_")) {
definePlugin.definitions[`process.env.${k}`] = JSON.stringify(v);
}
}
actions.replaceWebpackConfig(config);
};
I was running into the same issue and just found out what I was doing wrong. It looks like you're doing the same thing.
The explanation both the documentation and #coreyward give are correct, however, note that while corey implies they're two different approaches and the issue might be that they're conflicting, they're not, they do different things - so that code of yours is fine.
What's wrong, though, is that you're console logging process.env. And as it turns out, this will always output an empty object even though the variables might be there.
You have to console.log(process.env.GATSBY_APP) directly to see any value.
(Reference)
This is essentially an extension of what Corey pointed out in his "finally as a side-effect" section, however, the way he's written it implies it's an issue with destructuring - but it's not limited to that.
In my case, I was doing the above error AND not exposing the variables with GATSBY_ properly, then while testing I started logging the whole env object like you while I searched for the cause. This meant that even after I added the correct GATSBY_ prefix I still couldn't see anything.
So in short, it's probably only your console.log line that's an issue - access the variable directly, not the env object as a whole.
The Gatsby site as a well documented section on working with environment variables. The gist is that the environment variables are only available during build time when the internal nodejs server is server rendering your site. In order, get those environment variables in the browser you need to programmatically embed them using the special gatsby-*.js files. The example they provide seems to be close to what you want to achieve.

Why lodash get returns undefined for nested object in the react production build?

Actually, I know my question is s weird but really confused me. lodash functions are awesome and using them is a safe way to have a secure and clean code but in my react project when I use get function of lodash, in the development environment it works well as every developer expected.
import get from 'lodash/get';
const hostname = get(window, 'location.hostname');
// => returns the current hostname
But after I run yarn build && yarn start to make a production build of my ReactJS app and run it, its behavior is changed and returns undefined.
import get from 'lodash/get';
const hostname = get(window, 'location.hostname');
// => returns undefined
So in the production build, I try the get(window, 'location') and it returns the location object. but when I put a key of location the lodash get function returns undefined.
Actually, in the production and just for nested it returns undefined
Due to this issue, I just found this post, but no one answer it.
According to this comment I became passionate about testing my production build. So I listed all thing That happens on the production build of my project that maybe causes this issue.
At first, I doubted to babel plugins that I used for transpile, but none of them affect just on production, they affect for whole environments.
And at last, I find LodashModuleReplacementPlugin. this plugin causes this issue.
Based on its doc:
Deep property path support for methods like _.get, _.has, & _.set.
This plugin omit the deep path support on lodash get. That's the point.

Where is the variable named "global" coming from

I am refactoring a React 15 application (built with Webpack 2 and Babel) and I have noticed a lot of references to a global variable called global e.g. global.location. It's an alias for window, but I cannot find any code or configuration where the assignment occurs.
The Chrome devtools console can't access global so it is contained inside the modules that webpack generates. It's a very overloaded search term and I haven't had any luck tracking it down on Google.
Where is global coming from? Is there any benefit using it in a web application over window?
The global variable is handled specially by Webpack, not by Babel. Webpack's configuration file may contain a node section, which controls the polyfilling of various node objects, like global. Unless otherwise specified, global will be rewritten by webpack to mean window.
Example webpack.config.js turning off global rewriting:
module.exports = {
node: {
global: false
}
}
Documentation from project wiki.

Resources