My react routing is rendering the first child...but is not rendering the second child - react-dom

my App component is rendering... but not PdfPage. When I interchange the components, PdfPage is rendering, but not App. Please help!
import React from 'react';
import ReactDOM from 'react-dom';
import { App} from './App';
import { PdfPage } from './PdfPage';
import { BrowserRouter as Router, Routes, Route} from 'react-router-dom';
const routing = (
<>
<Router>
<Routes>
<Route exact path="/" element={<App />} />
<Route path={"/pdfPage"} element={<PdfPage />} />
</Routes>
</Router>
</>
);
ReactDOM.render(routing, document.getElementById('root'));

I tried this code and it works perfectly. Just to be sure, are you accessing pdfPage by going to localhost:3000/pdfPage right?

I figured out the problem. It was not in the program. I had to edit my snowpack.config.js to enable routing

Related

Solid App Router element not rendering component - Object Object

Just started using SolidJS and solid router, already stuck at the route not rendering the component inside "element". Instead it's showing "[object Object][object Object]"
See:
https://codesandbox.io/s/solidjs-shopping-cart-wj5zvr?file=/src/App.jsx
Below is the code:
import { Router, Route } from "solid-app-router";
function Home() {
return <h1>Home page here...</h1>;
}
function Cart() {
return <h1>Cart page here...</h1>;
}
function App() {
return (
<>
<header>header...</header>
<Router>
<Route path="/" element={<Home />} />
<Route path="/cart" element={<Cart />} />
</Router>
<footer>footer..</footer>
</>
);
}
export default App;
Try going with <Route path="/" component={Home} /> instead.
That also makes it wasy to convert to lazy routes (for code splitting) in the future...
<Route path="/" component={lazy(() => import("./home"))} />
EDIT: I took a look at your codesandbox and noticed there is already <Router> in index.jsx so what you want in App.jsx is actually <Routes>...<Routes>.
<Routes>
<Route path="/" component={Home} />
<Route path="/cart" component={Cart} />
</Routes>

React Leaflet Map not displaying

I have the basic example from React-leaflet, but for the life of me I cannot get anything to display. I am using this fix from Jeremy Monson for the common babel-loader issue. I was having the same problems of no display when I went through the manual fixes. Right now I am using styled-components, but I was having the same issue with regular CSS. My map component page looks like this.
import React from 'react'
import styled from '#emotion/styled'
import { MapContainer, TileLayer, Marker, Popup } from '#monsonjeremy/react-leaflet'
const Leaflet = styled.div`
height:500px;
width:500px;
`
const Map = () => {
return (
<Leaflet>
<MapContainer center={[51.505, -0.09]} zoom={13} scrollWheelZoom={false}>
<TileLayer
attribution='© OpenStreetMap contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={[51.505, -0.09]}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</MapContainer>
</Leaflet>
)
}
export default Map
I am loading the leaflet css in the of head my index.html page. I am importing my map component in App.js and rendering it there.
Any thoughts or pointing in the right direction would be much appreciated.
Add height to your map container using style prop:
<MapContainer
center={[51.505, -0.09]}
zoom={13}
scrollWheelZoom={false}
style={{height: '100%'}} // Add a height
>
...

Document null when testing with Testing Library

I'm trying to test a single component in my react app and getting the following error:
TypeError: Cannot read property 'clientWidth' of null
20 |
21 | resize = () => {
> 22 | const contentWidth = document.getElementById('root').clientWidth;
Here's the test:
import React from 'react'
import { MemoryRouter } from 'react-router-dom'
import { render, screen } from '#testing-library/react';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import reducer from '../store/reducer';
import Navigation from '../App/layout/AdminLayout/Navigation'
const store = createStore(reducer);
describe('Menu', () => {
it('Estate Planning points to classic estate planning page', () => {
render(
<MemoryRouter>
<Provider store={store}>
<Navigation />
</Provider>
</MemoryRouter>
);
screen.debug()
})
})
I tried with defining the container render(..., { container: document.body}), but got the same error. I'm not sure what I'm missing.
You are getting this error because your document does not contain an element with id "root" when running a test with react-testing-library. This is likely because react-testing-library renders your component to a different container than ReactDOM (which is used to run your application).
The Problem
Let's look at a typical React application setup.
<!-- public/index.html -->
<html>
<body>
<div id="root"></div>
</body>
</html>
// src/index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
ReactDOM.render(<App />, document.querySelector("#root"));
// src/components/App.js
import React from "react";
const App = () => <div>Hello World!</div>;
export default App;
As we can see, index.js looks for an HTML element with an id of "root" and renders our App component inside that element. We can confirm that is happening by inspecting the element in your browser's developer tools:
<html>
<body>
<div id="root">
<div>Hello World!</div>
</div>
</body>
</html>
Now, let's write a simple test, and see what the DOM looks like.
// src/components/App.test.js
import React from "react";
import { render, screen } from "#testing-library/react";
import App from "./App";
test("renders the component", () => {
render(<App />);
screen.debug();
});
screen.debug() prints the DOM for debugging purposes. We can see that it does not include an element with id "root":
<body>
<div>
<div>
Hello World!
</div>
</div>
</body>
So the DOM container is slightly different for your test vs. runtime.
The Solution
One way to fix this problem is to refactor your code not to be dependent on the "root" element. Another option is to tell react-testing-library to render your component in a custom container. Here is an example of what that might look like:
// src/components/App.test.js
import React from "react";
import { render, screen } from "#testing-library/react";
import App from "./App";
test("renders the component in a specific container", () => {
const container = document.createElement("div");
container.id = "root";
render(<App />, { container: document.body.appendChild(container) });
screen.debug();
});
Now, we can see an element with id of "root" in the DOM, so your component should be able to find that element.
<body>
<div id="root">
<div>
Hello World!
</div>
</div>
</body>

Material popover does not close upon onClose call

Have this Chat component and inside an input have an en endorsement, inside that i want to have a popover to show and pick emojis, The pop over pops up but the closing functionality does not work.
import React from "react";
import "./styles.css";
import Chat from "./Chat";
export default function App() {
return (
<div className="App">
<Chat />
</div>
);
}
Here is a sandbox example of that.
https://codesandbox.io/embed/zealous-maxwell-3115b?fontsize=14&hidenavigation=1&theme=dark
<InputAdornment position="end">
<IconButton aria-describedby={id} onClick={handleEmojiClick}>
<EmojiEmotionsIcon />
</IconButton>
<PopOver
open={open}
id={id}
anchorEl={anchorEl}
setAnchorEl={setAnchorEl}
/>
<IconButton>
<SendIcon />
</IconButton>
</InputAdornment>
Just puted the Popover out of IconButton Component and it is working now.

Customizing react-leaflet marker icons by using font awesome

It is more theoretical question, rather than a problem.
How to use font awesome icons as react-leaflet map marker icons?
I would like to have such an icon selector control to assign(customize) each marker icon I have got on my map. By the way I am using JSX components of Map and Marker.
Is it possible to achieve this?
Anybody have a sample pen about this? I have really googled it strongly but couldn't find any plugin but a fontawesome plugin that is working only with Leaflet 1.0.
So any idea appreciated.
Thanks in advance.
For some reasons code is not getting formatted. See code on code sandbox
Here is how you can use font-awesome icons as markers.
Add font-awesome CDN to your index.html
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU"
crossorigin="anonymous">
Use divIcon along with renderToStaticMarkup from react-dom/server to generate icon for marker. And pass this divIcon to Marker as a icon prop.
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { renderToStaticMarkup } from 'react-dom/server';
import { divIcon } from 'leaflet';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import './styles.css';
class App extends Component {
state = {
lat: 51.505,
lng: -0.091,
zoom: 13,
};
render() {
const position = [this.state.lat, this.state.lng];
const iconMarkup = renderToStaticMarkup(<i className=" fa fa-map-marker-alt fa-3x" />);
const customMarkerIcon = divIcon({
html: iconMarkup,
});
return (
<Map center={position} zoom={this.state.zoom}>
<TileLayer
attribution="&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"
url="https://{s}.tile.osm.org/{z}/{x}/{y}.png"
/>
<Marker position={position} icon={customMarkerIcon}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</Map>
);
}
}
const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);
Override divIcon default style by adding the following class to your css file
.leaflet-div-icon {
background: transparent;
border: none;
}
Here is a working example of the same:
https://codesandbox.io/s/4ry180jl34
For those who already use the React components of Fontawesome (FontAwesomeIcon), there is a solution that does not require importing via CDN again. It uses the same principles of Murli's answers, but instead of adding <i className=" fa fa-map-marker-alt fa-3x" />, you can convert the FontAwesomeIcon component to html and pass that into the html attribute of the divIcon. It would look like this (adapted the example of the accepted answer):
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import ReactDOMServer from 'react-dom/server';
import Leaflet from 'leaflet'
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import './styles.css';
// FontAwesome requirements
import { faUserAstronaut } from '#fortawesome/free-solid-svg-icons'
library.add(faUserAstronaut)
class App extends Component {
state = {
lat: 51.505,
lng: -0.091,
zoom: 13,
};
render() {
const position = [this.state.lat, this.state.lng];
const iconHTML = ReactDOMServer.renderToString(<FontAwesomeIcon icon='user-astronaut' />)
const customMarkerIcon = new Leaflet.DivIcon({
html: iconHTML,
});
return (
<Map center={position} zoom={this.state.zoom}>
<TileLayer
attribution="&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"
url="https://{s}.tile.osm.org/{z}/{x}/{y}.png"
/>
<Marker position={position} icon={customMarkerIcon}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</Map>
);
}
}
const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);
Create divIcon and insert it into icon property:
// marker-icons.js
import L from 'leaflet';
const factory = new L.divIcon({
className: '',
iconAnchor: [12, 25],
labelAnchor: [-6, 0],
popupAnchor: [0, -15],
iconSize: [25, 41],
html: `<span class="fa fa-industry"></span>`
});
export default { factory };
Use icon in component file:
// component.js
import { factory } from './marker-icons';
<MapContainer center={[12.23432, 87.234]} zoom={6} scrollWheelZoom={false}>
<TileLayer attribution='© OpenStreetMap contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
<Marker position={45.4534, 23.43]} icon={factory}>
<Popup>Help text</Popup>
</Marker>
</MapContainer>