Render Map child from outside MapContainer - reactjs

I would like to render a child inside <MapContainer> from outside the initial MapContainer. Is this possible somehow?
In react-leaflet-v3 I render a lot of items on the map by passing the map object via a reference. But for my current situation I wold like to render a react button on top of the map based on routing.
One way of doing this is to add nest <Route />. inside the MapContainer. This however is not ideal because of the scattered route behaviour...
Is it possible in another way?

I used the portal way to solve my problem:
In my map-container, this is happening:
const [control, setControl] = useState(null);
const handleRef = useCallback((instance) => setControl(instance), [
setControl,
]);
...
<MapContainer ...>
...
<div className="mapcontrol-top-left" ref={handleRef}></div>
</MapContainer>
In a totally different component, where conditionally I want to show something on the Map, I do this (using Material-UI Portal & Fab component):
<Portal container={props.control}>
<Fab size="medium">
<EditIcon />
</Fab>
</Portal>
The material-ui Portal component is easy to use and adds convenience, but a native React Portal will also do the trick...

Related

How would you pass a Markdown component to a React or Preact component in Astro?

Similarly to how you can pass Markdown components to Astro components, I want to import one into a React/Preact component.
It didn't seem to be working directly when I imported the component into the React/Preact, so I tried passing them in from the parent Astro component like so:
<DemoContent
blog={(<Blog />)}
tweet={(<TweetThread />)}
highlight={(<HighlightClips />)}
client:visible
/>
...but that gives me ERROR: Expected ">" but found "/".
What is the suggested way of doing this?
(Follow-up from a discord conversation. Thanks for making this public!)
When passing Astro or Markdown components to a framework like Preact, you'll need to use "slots." You can use slot="prop-name" to wire those up like so:
<DemoContent>
<Blog slot="blog" />
<TweetThread slot="tweet" />
<HighlightClips slot="highlight" />
</DemoContent>
Then, in your Preact component, you can access blog, tweet, and highlight as props. You'll render these similar to the {children} prop:
export function DemoContent({ blog, tweet, highlight }) {
return (
<section>
{blog}
{tweet}
{highlight}
</section>
)
}
These will also map to Vue or Svelte slots if you happen to use those frameworks. Hope this helps!

How is it possible to make one component stand out from other same component in React

I was creating React project and I have component which is used in several places in the project. The question is how is it possible to make one certain different from other instances of that component in terms of css styling?
For achieving that you have to accept the styles of the component as props. And each time you use the component pass the desired style to each instance.
For example
const PopupHeader = ({ title, onClose, classes }) => (
<div className={classNames(styles.head, classes.header)}>
<span className={styles.headText}>
{title}
</span>
</div>
);
Here the PopupHeader component is receiving classes as props which is actually an object of styles passed from parent component, which is used in the child component.
Hope it helps.
You can use contextAPI for sending the styles in all components
<ParentComponent>
<Style.Provider value={{ style: "background: "white .. or something" }}>
{this.props.children}
</Style.Provider>
</ParentComponent>
You can send the styles in all child components

ReactJS: Dynamic Navbar Component determined by component prop

In my app, in the navbar, the menu hamburger and the back button are sharing the same space, and one or the other is shown based on page.
I would like to implement something like :
<Nav/>
<Page nav={backButton}/>
or
<Page nav={Menu}/>
Any ideas or links to docs would be greatly appreciated
Thanks!
Normally I'd try to make this prop driven. Your parent component can pass down a showBackButton prop that acts as a switch.
{ showBackButton ? <BackButton /> : <HamburgerMenu /> }

Passing components into another in react

I have an app with a number of components. One of the components I need be to able to pass different variations of another two components into, based on a layout. I believe it can be passed in like a data attribute, but I'm unsure of the exact syntax to push the other components in.
Given two components <List /> and <Box /> which are currently in another component being imported into my main App.js file as such:
export const CallOut = () => {
return(
<div style={styles.sectionInner}>
<List />
<BoxRight/>
</div>
)
};
where <CallOut /> is being imported into App.js, I'd like to pass those two components into the <CallOut /> component.
What is the correct syntax to pass those two in and have them placed in the same spot they're currently in within the CallOut component?
I believe it should be something similar to
<CallOut param={List} param={BoxRight} />
but I know this isn't right.
You can use capital names for props, and use these to instantiate react components like this:
export const CallOut = ({List, Box}) => (
<div style={styles.sectionInner}>
<List/>
<Box/>
</div>
);
List and Box are the properties of this component. You can instantiate it like this:
<CallOut List={SomeComponent} Box={SomeOtherComponent}/>
I don't know if we're on the same page but maybe you're looking for children property ?
So your component will look like that:
export const CallOut = ({children}) => (
<div style={styles.sectionInner}>
{children}
</div>
);
And usage:
<CallOut >
<List/>
<Box/>
</CallOut>
You can pass any component as CallOut child or even do some filtering using children API
It's common usage when components don’t know their children ahead of time and it's used just for some kind of boxing/wrapping.

What is causing my component to unmount?

I'm making an app where I have an Overlay component and a Map component rendering behind it just like this:
<div>
{showOverlay && <Overlay />}
<Map /> // this component should mount once
</div>
The overlay is shown to let the map load underneath but when I remove the Overlay (set showOverlay to false here) the Map component re-load.
At first I thought the Map component was just re-rendering, but after some digging I discovered that the component was actually re-mounting.
If I log in the componentWillMount, componentWillUnmount and render methods, the log appear in that order (which seems contradictory)
render
willUnmount
willMount
The parent does not re-mount, only the Map component do.
The Map component just render a div that reference a mapbox-gl-js map (like this https://gist.github.com/tristen/5c4b346ae38892f732504e6785d87057#file-map-js)
What can cause my component to re-mount itself like that ?
Thanks !

Resources