HeadlessUI switch Tabs with Navbar - reactjs

i have a Tabs-Section (headlessui) and in my Navbar has Links/Buttons for each Tab. My Problem is now that i don't know how i controll the Tabs with the buttons/links in the Navbar. And yes the Tabs are also controlled by the Tab.List.
The Page is structured like this:
<app>
<IndexPage(File)>
<LayoutComponent> // in this component is the navbar-component
{content}
<SectionComponent>
<Tabs.Group>
...
</Tabs.Group>
</SectionComponent>
{content}
<LayoutComponent>
</IndexPage>
</app>
And i tried to handle the TabIndex with react-state (like this) but i don't know how to forward a state through so many components.
My second try was with URL-Querys, but this have many bugs, and it worked not really good.
Is there a way to solve my Problem?
ps: my project is with nextjs

I'm now using the React Context API to build a DataProvider and it works perfectly

Related

Does importing a component for use with React-Router display the stylesheets used in that component, even when that component is not being rendered?

While using react-router for a multi-page react app, I've found that the different components that are to be rendered based on the path display the stylesheets in those components, even when the corresponding component isn't displayed.
I was playing around with adding a Sponsors page to my website, and the CSS was behaving strangely. Digging deeper into the problem with chrome devtools, I found that the css from my homepage was on the page while it was not being displayed, causing unexpected styles.
I've tried researching if this is the expected behaviour without any luck. I removed the homepage from my routing code and the styles behaved as expected in the other component, proving that that import was the problem.
My routing code:
<Switch>
<Route
exact path="/"
render={props => <MainPage language = {this.state.language}/>}
/>
<Route
path="/Sponsors/"
render={props => <Sponsors language = {this.state.language}/>}
/>
</Switch>
Of course with
import Sponsors from './Pages/Sponsors/Sponsors.js'
import MainPage from './Pages/MainPage/MainPage.js';
at the top of that file.
and at the top of MainPage.js:
import './MainPage.css';
An import that looks like that, and the same type in Sponsors.css.
Any code in that MainPage.css will affect the elements in the Sponsors component, even when the url is at /Sponsors (i.e. the MainPage component shouldn't be rendering).
I'm looking to ensure I understand the behaviour of react-router, that the MainPage.css should not appear when MainPage is not being rendered. As an alternative I could write specific enough css that this never happens, but It was my understanding that the modular nature of react featured that not being a necessity, as in I can write it only specific enough for the code being rendered. Am I mistaken?
I understood you are trying to limit the scope of CSS to a module, generally it is having a global scope. you can use "CSS Modules", to overcome this behaviour.
please find the article from facebook.
https://facebook.github.io/create-react-app/docs/adding-a-css-modules-stylesheet
hope it will help to fix the issue.

How to override Back button when a drawer is showing in React 16 / Router V4

I have a structure like this, there's a route like:
<Route path="/sample-route" component={ComponentA}/>
Then ComponentA has:
<ComponentA>
<ComponentB/>
<ComponentC>
<MaterialUIDrawer/>
</ComponentC>
</ComponentA>
ComponentC is used in 5 different routes as a child. The MaterialUIDrawer is showing based on a flag in a redux reducer. The problem I'm trying to solve is when the drawer is open, clicking back hides it but also navigates back. I tried solving it like this:
window.onpopstate = (e) => {
if (this.props.isOpen) {
this.props.toggleDrawer(false);
this.props.history.replace(this.props.match.url);
}
};
This has 2 issues:
If this is the first page you land on, it doesn't actually do anything, the function doesn't trigger
If you are on a different site and navigate to the url that contains the drawer, hitting Back moves you to a different URL (different domain)
I also tried setting a <Route/> in ComponentC and then the drawer lives there, but I didn't manage to get it to work, maybe the path is wrong. It felt like this might be the right way though, if path is /path1, then drawer lives in /path1/drawer, or /path2/drawer, etc.
I'm trying to find a way for the Back button in a browser to close the drawer (so execute a function I define) and override the default functionality.
I think you should be using props here instead of paths, so something like /path1?drawer=1, but you will definitely need to use history/location so that the back button can actually go back, so you are on the right trail.
I'm not sure what you are using for a browser history manager, but I would recommend tying off of that instead of leaning on the window pop-state. Your history module should be the source of truth and feed redux, not the other-way around IMO.

Semantic-UI-React Responsive component renders element in spite of minWidth/maxWidth prop

I have a component where I want to render different components based on screen size. If I reload the page while on mobile view, everything is ok, NavBarMobile is rendered and NavbarDesktop is not.
If I reload the page while on desktop view, then my NavbarMobile is rendered again instead of NavBarDesktop.
If I start resizing the screen to mobile and back to desktop view, NavBarDesktop is rendered correctly.
So, the problem is first page load while in Desktop view, how to fix that?
const { mainAppComponents, } = this.props
const { visible, } = this.state
return (
<Fragment>
<Responsive maxWidth={767}>
<NavBarMobile
onPusherClick={this.handlePusher}
onToggle={this.handleToggle}
rightItems={rightItems}
visible={visible}
>
{mainAppComponents.header}
{mainAppComponents.routes}
</NavBarMobile>
</Responsive>
<Responsive minWidth={768}>
<NavBarDesktop rightItems={rightItems}>{mainAppComponents.header}</NavBarDesktop>
{mainAppComponents.routes}
</Responsive>
</Fragment>
)
Igor-Vuk, I put together a quick codesandbox example just to make sure there was not a problem with how you are trying to implement the min/max width props. As you can see from this example, they do in fact work as expected. https://codesandbox.io/s/98pk46l7vr
Without seeing the rest of your component, or application, the issue may be due to something in your router. I'd recommend trying to remove some of the other components you are returning as children of the Responsive component to see if it starts working as expected (like in my codesandbox example). If it works, then you know the problem is somewhere in the children. If it does not work then there is a greater problem above in your app.
If you are using SSR, on initial load the content was rendered and served with the Responsive component having no knowledge of the viewport. So you may need to also add a CSS media query.

Does React have keep-alive like Vue js?

I made a Todo list with React js. This web has List and Detail pages.
There is a list and 1 list has 10 items. When user scroll bottom, next page data will be loaded.
user click 40th item -> watch detail page (react-router) -> click back button
The main page scroll top of the page and get 1st page data again.
How to restore scroll position and datas without Ajax call?
When I used Vue js, i’ve used 'keep-alive' element.
Help me. Thank you :)
If you are working with react-router
Component can not be cached while going forward or back which lead to losing data and interaction while using Route
Component would be unmounted when Route was unmatched
After reading source code of Route we found that using children prop as a function could help to control rendering behavior.
Hiding instead of Removing would fix this issue.
I am already fixed it with my tools react-router-cache-route
Usage
Replace <Route> with <CacheRoute>
Replace <Switch> with <CacheSwitch>
If you want real <KeepAlive /> for React
I have my implementation react-activation
Online Demo
Usage
import KeepAlive, { AliveScope } from 'react-activation'
function App() {
const [show, setShow] = useState(true)
return (
<AliveScope>
<button onClick={() => setShow(show => !show)}>Toggle</button>
{show && (
<KeepAlive>
<Test />
</KeepAlive>
)}
</AliveScope>
)
}
The implementation principle is easy to say.
Because React will unload components that are in the intrinsic component hierarchy, we need to extract the components in <KeepAlive>, that is, their children props, and render them into a component that will not be unloaded.
Until now the awnser is no unfortunately. But there's a issue about it in React repository: https://github.com/facebook/react/issues/12039
keep-alive is really nice. Generally, if you want to preserve state, you look at using a Flux (Redux lib) design pattern to store your data in a global store. You can even add this to a single component use case and not use it anywhere else if you wish.
If you need to keep the component around you can look at hoisting the component up and adding a "display: none" style to the component there. This will preserve the Node and thus the component state along with it.
Worth noting also is the "key" field helps the React engine figure out what tree should be unmounted and what should be kept. If you have the same component and want to preserve its state across multiple usages, maintain the key value. Conversely, if you want to ensure an unmount, just change the key value.
While searching for the same, I found this library, which is said to be doing the same. Have not used though - https://www.npmjs.com/package/react-keep-alive

React Component: Foundation Modal (Reveal) won't open

So I've just started learning React and Redux, so I apologize if this is a very noobish question. But I've emptied my Google quote, and can't find anything that helps me.
My problem is: I work on a site with React, Redux, and Foundation 6. One of my React components have a link, that when clicked, should open a Modal with a specific warning for that link. So I've created a component with my modal markup:
ComponentModal.js:
import React, { PropTypes } from 'react';
const Modal = () => (
<div className="reveal" id="exampleModal1" data-reveal>
<h1>Awesome. I Have It.</h1>
</div>
);
export default Modal;
The component with a link renders some stuff, but basically have a
<a data-open="exampleModal1">Click me for a modal</a>
tag in it's render.
And although inspecting the page confirms that the markup for the modal exists, nothing happens when i click the link.
If I move the popup from the component, and into the DOM, the link works.
Some trial and error shows me, that if i manually run $(document).foundation(); in the console when ComponentModal is rendered, the popup works as intended.
So my question is kinda two questions:
1. How do I, in Redux, run $(document).foundation(); when my ComponentModal is done rendering? Maybe I'm wrong, but I don't have the componentDidMount() method available to me, where it might make sense to make that call?
2. Is this a totally wrong way to go about it?
Hope it's not too confusing and not too dumb a question :)
FYI, this question/solution has nothing to do with REDUX!
The problem is that you're trying to use React AND Jquery to make your page do cool things.
You should really choose one or the other.
$(document).foundation() is a Jquery library.
Instead you should use something like React Foundation which removes the jquery dependency and gives you foundation components built with react.
You can do $(document).foundation() in React inside componentDidMount of the component that has the reval modal or better yet You can do this inside componentDidMount of the top most partent in your app.
componentDidMount in React runs once after all the DOM nodes related to that component is mounted. What $(document).foundation() does, if it runs inside componentDidMount, is that it binds event handlers on the elements that have foundation realated attributes like data-dropdown or data-reveal.
componentDidMount() {
$(document).foundation();
}

Resources