react-leaflet mapboxgl integration not working - reactjs

following the answer in this page :
Render mapbox vector tiles inside react-leaflet?
When i export MapBoxGLLayer and import it to my main class,
like
import MapBoxGLLayer from './MapBoxGLLayer';
and try to access it in my render function, like:
<Map>
<MapBoxGLLayer
accessToken={MAPBOX_ACCESS_TOKEN}
style='https://style.example.com/style.json'
/>
</Map>
i'm getting this error which is pretty consistent.
MapLayer.js:77 Uncaught TypeError: Cannot read property 'layerContainer' of undefined
at VectorgridLayer.get (MapLayer.js:77)
at VectorgridLayer.componentDidMount (MapLayer.js:38)
There is no leaflet to the props.
I don't know what am I doing wrong here.

Taking hints from the answer you mentioned, I was able to get it working.
Your MapBoxGLLayer.js
import L from "leaflet";
import {} from "mapbox-gl-leaflet";
import PropTypes from "prop-types";
import { GridLayer, withLeaflet } from "react-leaflet";
class MapBoxGLLayer extends GridLayer {
createLeafletElement(props){
return L.mapboxGL(props);
}
}
export default withLeaflet(MapBoxGLLayer);
The missing thing was the withLeaflet HOC.
Usage:
npm i mapbox-gl-leaflet
Add mapbox-gl-js and css to index.html
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.css' rel='stylesheet' />
// Import the MapBoxGLLayer component mentioned above.
class App extends Component {
state = {
center: [51.505, -0.091],
zoom: 13
};
render() {
return (
<div>
<Map center={this.state.center} zoom={this.state.zoom}>
<MapBoxGLLayer
accessToken={MAPBOX_ACCESS_TOKEN}
style="mapbox://styles/mapbox/streets-v9"
/>
</Map>
</div>
);
}
}
You can find the working example here:https://codesandbox.io/s/ooypokn26y
Add your own mapbox token to see it working.

It seems to be a bug in mapbox-gl-leaflet version 0.0.3 that is the "latest" in npm and was released two years ago.
onRemove: function (map) {
if (this._map.options.zoomAnimation) {
L.DomEvent.off(this._map._proxy, L.DomUtil.TRANSITION_END, this._transitionEnd, this);
}
map.getPanes().tilePane.removeChild(this._glContainer);
this._glMap.remove();
this._glMap = null;
}
The object this.map._proxy is not defined. Solution is to disable zoom animations with zoomAnimation={false} in the React Map Component. Then the branch is not taken in mapbox-gl-leaflet and you won't get this error.
This problem is solved in the master branch of mapbox-gl-leaflet in GitHub:
https://github.com/mapbox/mapbox-gl-leaflet/blob/954875e2e4269db313c99d522689bc08f4aadad2/leaflet-mapbox-gl.js
So try to update you libs.

Related

Uncaught ReferenceError: require is not defined react-rails

I'm trying to integrate react-rails 2.6.1 within my rails 4.2.11 app.
initially started with webpacker but it's giving me troubles with the actual prod deployment, so I removed webpacker and just pack stuff with sprockets 3.7.2.
The page is loaded properly but the react_component is not shown.
in the html source it's just rendered as a div:
<div data-react-class="Sidebar" data-react-props="..." data-react-cache-id="Sidebar-0"></div>
but nothing is shown.
in the console I can see:
Uncaught ReferenceError: require is not defined
which causes later on:
Cannot find component: 'Sidebar'. Make sure your component is available to render.
this is the definition of my react component:
import React from "react"
class Sidebar extends React.Component {
render() {
return (<p> hello from react </p> );
}
}
I've tried moving imports from application.js up and down, (according to https://github.com/reactjs/react-rails/wiki/Troubleshooting) to no help.
Try to export your component to be able to import it
import React from "react"
class Sidebar extends React.Component {
render() {
return (<p> hello from react </p> );
}
}
export default Sidebar;

Ract FontAwesome ES6 usage

Good day
I am a novice React developer building a site for a client using ES6 standards. I have found a component for which the usage as description uses an older syntax, and I am having some trouble implementing my code. I am receiving an error message that I am not sue how to resolve.
The component in questions can be seen here:
https://www.npmjs.com/package/react-fontawesome
it instructs you to use the component as follows:
var React = require('react');
var FontAwesome = require('react-fontawesome');
React.render(<FontAwesome name='rocket' />, document.body);
To my understanding, this is an older way of writing React code. I have thus updated my code to for the ES6 standard.
I scratched in my package.json file to find out where to import the component from, so I am not sure if this is perhaps where I have gone wrong.
Below is a copy of my code using what I believe to be the correct implementation:
import React, { Component } from "react";
import FontAwesome from '#fortawesome/fontawesome-svg-core';
export class Footer extends Component {
constructor(props) {
super(props);
}
render = _ => {
return (
<div>
<FontAwesome name='rocket' />
</div>
);
}
}
When I import the component and run the code I get the following error:
React.createElement: type is invalid -- expected a string (for
built-in components) or a class/function (for composite components)
but got: undefined. You likely forgot to export your component from
the file it's defined in, or you might have mixed up default and named
imports.
Check the render method of Footer.
in Footer (created by App)
in div (created by App)
If anyone would be kind enough to let me know where I might be going wring, I would be incredibly grateful.
There's a simple example on their docs page that should help out:
import ReactDOM from 'react-dom'
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faCoffee } from '#fortawesome/free-solid-svg-icons'
const element = <FontAwesomeIcon icon={faCoffee} />
ReactDOM.render(element, document.body)

Unresolved variable WebStorm this.props

I use WebStorm for React JS and I'm getting this 'Unresolved variable warning' for all props.
I searched for solution everywhere but couldn't find. Whenever i pass down prop value and then use it as this.props.something, that something is unresolved. App works fine and there is no problem, it's just that WebStorm makes this irritating. I installed typescript definitions and nothing.
This is the code:
import React from 'react';
import ReactDOM from 'react-dom';
class A extends React.Component
{
render()
{
return (
<button>
{this.props.something}
</button>
);
}
}
class B extends React.Component
{
render()
{
return(
<A something={1}/>
)
}
}
ReactDOM.render(
<B/>,
document.getElementById('root')
);
Here is screenshot of that:
Screenshot
Known issue, please follow WEB-31785 for updates
npm install --save #types/react
use es6 destructuring to remove the warnings:
eg : rather than
if (this.props.variableName) ...
use
const { variableName } = this.props;
if (variableName) ...

RaisedButton not working at all

I have included material-ui (and react-tap-event-plugin) in my project and added 3 buttons to one of my components:
<RaisedButton onClick={this.props.onSave} label="Save" style={styles.button}/>
<RaisedButton label='Publish' onClick={this.props.onPublish} style={styles.button}/>
<RaisedButton label='Cancel' onClick={this.onCancel.bind(this)} style={styles.buttonCancel}/>
when I click on any of these, they go very dark grey and when I click again, they go black (and stay like that). The whole applications goes bonkers, the react routing no longer works (I can see the URL changing in the address bar, but the view doesn't refresh). This all looks pretty bad for a button click :)
Any idea what I may be doing wrong? (I take care of the childContext as described in the docs, so the muiTheme is loaded).
I forgot to check the console... there are 3 exceptions whenever I press the button:
1)
vendor.js:12 Uncaught Error: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded (details: https://facebook.github.io/react/warnings/refs-must-have-owner.html).(…)
2)
ReactTransitionGroup.js:176 Uncaught TypeError: Cannot read property 'componentWillLeave' of undefined(…)
3)
vendor.js:12 Uncaught Error: removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might be removing a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded (details: https://facebook.github.io/react/warnings/refs-must-have-owner.html).(…)
In the component that uses FlatButton (or RaisedButton neither work) I have this:
1) Import:
import FlatButton from 'material-ui/FlatButton'; //eslint-disable-line
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
2) in the class
getChildContext() {
return { muiTheme: getMuiTheme(baseTheme) };
}
3) and a static declaration:
EditorComponent.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
};
Feels like I'm doing all that's required.
This may be related to what I'm experiencing:
https://github.com/callemall/material-ui/issues/2818
So probably the issue is caused by material-ui distributing it's own version of React? What's the point in that? But... my version of material-ui doesn't have a node_modules folder, so no extra React either...
Source for a component importing and using FlatButton
import React from 'react'; // eslint-disable-line
import Input from '../../../components/common/textInput'; // eslint-disable-line
import BaseEditorComponent from '../base/EditorComponent';
import FlatButton from 'material-ui/FlatButton'; //eslint-disable-line
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
export default class EditorComponent extends BaseEditorComponent {
constructor() {
super();
this.state = {
textValue: 'Enter value'
};
}
getChildContext() {
return { muiTheme: getMuiTheme(baseTheme) };
}
_onChange(e) {
this.setState({
textValue: e.target.value
});
}
render() {
return (
<div>
<Input
value={this.state.textValue}
name="SimpleText"
label="Simple Text Value:"
onChange={this._onChange.bind(this)}
/>
<FlatButton label="Test"/>
</div>
);
}
}
EditorComponent.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
};
Also, the BaseEditorComponent:
import React from 'react';
import widgetActions from '../../widgets/WidgetActions';
import widgetInstanceStore from '../../widgets/WidgetInstanceStore';
export default class EditorComponent extends React.Component {
constructor() {
super();
}
componentDidMount() {
this.setState(widgetInstanceStore.getWidgetInstanceState(this.props.widgetId) || {});
}
save() {
widgetActions.saveWidgetInstanceState(this.props.widgetId, this.state);
}
}
Have you tried to use onTouchTap instead of onClick?
If #1 doesn't help, please show more code - component with above code and it's parent component.
As per https://github.com/callemall/material-ui/issues/2818 the solution was to include react-addons-transition-group alongside react in the browserify bundle. So it's good to know that it's not only NPM where a 2nd copy of react can slip through, but also browserify or webpack.
Thanks https://stackoverflow.com/users/3706986/piotr-sołtysiak for helping with the issue today!

Using marked in react

I want to use marked in reactjs as described in the reactjs docs.
<div>{marked(mystring)}</div>
I use babel so I import marked like this:
import { marked } from 'marked';
Unfortunately the import statement does not work. marked is not defined.
How do I have to import marked here, so that I can use it?
Here's one way to use marked with React:
Ensure that you've installed marked
Include marked in your project's package.json file:
// package.json
{
dependencies: {
react: "^17.0.0",
marked: "^4.0.0",
},
}
Import marked in your .jsx (or related) file:
import { marked } from "marked";
Use the dangerouslySetInnerHTML approach as shown in the example below:
import React from "react";
import { marked } from "marked";
class MarkdownExample extends React.Component {
getMarkdownText() {
var rawMarkup = marked.parse("This is _Markdown_.");
return { __html: rawMarkup };
}
render() {
return <div dangerouslySetInnerHTML={this.getMarkdownText()} />;
}
}
The dangerouslySetInnerHTML attribute gives you the ability to work with raw (HTML) markup. Make sure to take care when using this attribute, though!
Alternative (Safe)
If you don't want to use dangerouslySetInnerHTML and safely render HTML. Try marked-react, which internally uses marked to render the html elements as react components
npm i marked-react
import Markdown from "marked-react";
const MarkdownComponent = () => {
return <Markdown>{rawmarkdown}</Markdown>;
};
Another alternative is react-markdown
Here is another way of using marked with React Hooks:
Create your MarkedConverter component
import { useState } from 'react'
import marked from 'marked'
export const MarkedConverter = () => {
const [markedVal, setMarkedVal] = useState(
'# Welcome to my React Markdown Previewer!'
)
return <div dangerouslySetInnerHTML={createMarkUp(markedVal)}></div>
}
Create Markup function and pass the value from MarkedConverter Component
export const createMarkUp = (val) => {
return { __html: marked(val) }
}
Finally you can import MarkedConverter Component to any of your Component
With the marked-wrapper react-marked-markdown:
import { MarkdownPreview } from 'react-marked-markdown'
export default ({ post }) => (
<div>
<h1>{ post.title }</h1>
<MarkdownPreview value={ post.content }/>
</div>
)
If you just want to import marked:
import marked from 'marked';
Then call the function in your component:
marked('# Markdown');
Here's an example on how to use marked with react:
Install marked with NPM : npm i marked
import it in your react app (this example is created with create-react-app), and using it
example of a react component using "marked"
result in the browser :
preview

Resources