React Bootstrap - Controlled Carousel does not scroll anymore - reactjs

I use React Bootstrap Carousel in my GatsbyJS project.
I have an issue with the controlled carousel because does not scroll anymore.
I use in a component that display 3 Carousel items.
const SimpleCarousel = () => {
const [index, setIndex] = useState(0)
const items = [1, 2, 3]
function handleSelect(selectedIndex, e) {
setIndex(selectedIndex)
}
return (
<Carousel
activeIndex={index}
onSelect={handleSelect}
>
{items.map((item) => (
<Carousel.Item key={`carousel-item-${item}`}>
<h2>Title {item}</h2>
</Carousel.Item>
))}
)
}
export default SimpleCarousel;
I use activeIndex with a state and onSelect handler as in documentation, but the handler function is not called and the active index does not change.
It works with multiple <Carousel.Item> but not after a map.
Configuration :
Windows 10
node : 12.16.1
react-bootstrap : 1.6.1
boostrap : 4.6.0

I have created a sandbox and copy pasted your code. I noticed that the closing tag of carousel is missing: </Carousel>. Maybe this is the problem and you don't get a proper error somehow?
Anyway the sandbox is working just with copy/pasing your code. The items are changing after few seconds. The onSelect handler is called every time: https://codesandbox.io/s/winter-monad-hv83g4
This is react-boostrap v2 though. I can't manage to add an older version of it as dependency (v1). So when then sandbox is working and yours are not, I assume it's a react-bootstrap 1.6.1 specific issue.

Related

React - Bootstrap: Offcanvas with embedded mapped tabs content disappearing on Re-Render

I have a React application that includes a Bootstrap Offcanvas component with embedded Tabs. For the Tabs and Content, they are created from an array of Table components which is mapped to create them dynamically. These Table components take a container as input, which I used a Ref to bind them to the dynamically generated Tabs. The first render works perfectly, however; when I close the Offcanvas and open it again, the Tab content is now empty. I'm assuming this is an issue with the Ref.
Here is the code for the Tab component.
import React, { useEffect, useRef } from 'react';
import Tabs from "react-bootstrap/Tabs";
import Tab from "react-bootstrap/Tab";
function LayerResults({featureTables, mapView, placeFeatureTables}) {
const resultRef = useRef(featureTables.map(() => React.createRef()));
useEffect(()=> {
if (featureTables.length) {
placeFeatureTables(resultRef);
}
}, [mapView])
return (
<Tabs defaultActiveKey={featureTables[0].layer.title} className="tableResults">
{featureTables && featureTables.map((table, i) => {
return (
<Tab
className="TableTab"
title={`${table.layer.title.slice(0,10)}...`}
eventKey={table.layer.title}
key={`${i}`}
>
<div ref={resultRef.current[i]}></div>
</Tab>
)
})}
</Tabs>
)
};
And here's the code for the placeFeatureTables() function from an even higher component that the useEffect uses which updates the featureTables state with the container / Ref.
const placeFeatureTables = (containerRefs) => {
setFeatureTables(prev => {
const placedTables = prev.map((table, i) => {
table.container = containerRefs.current[i].current;
return table;
})
return placedTables;
})
}
I feel like this is most likely the issue area and the Containers / Refs are not being updated properly on re-render and I should be using something other than useRef. The thing that's really bugging me though, is that I swear this was working earlier.
Note1: The FeatureTables come from ESRI ArcGIS Javascript API. Although, it's just the Ref being passed, so I don't think it's necessary to know about them. FeatureTable Documentation
Note2: If I console.log the featureTables. The first time, the container highlights the area where it's at. Once I close and re-open and then click on the new featureTables container, it says the node does not exist.

React onDrag not working but onDragStart works

I have a simple component with a draggable icon next to it (going to implement my own Resize).
The code is as follows:
type ICanvas = {
currPageId:string
}
const Canvas:FC<ICanvas> = ({currPageId}) => {
const story = useStoryStore(state=>state.story);
const handleDragStart = (e:any) => {
console.log("start")
};
const handleOnDrag = (e:any) => {
console.log("on drag");
};
return (
<Box {...Styles.CanvasContainer} pos='relative'>
<div
className="resize-button"
draggable
onDrag={handleOnDrag}
onDragStart={handleDragStart}
onDragEnd={handleOnDrag}
>
<HorizonIcon type='arrow_chevron_down'/>
</div>
</Box>
)
}
export default Canvas;
The onDragStart event fires as it should, but onDrag doesn't work. I tried adding e.stopPropagation/preventDefault everywhere in all possible permutation but nothing.
I even tried using the Chrome inspect event breakpoints and nothing.
I am using latest react version with Chakra UI provider.
Thanks!
So after some digging and a little bit of luck I found out that I had in my system a dependancy of React-dnd-HTML5backend.
With a little google research I found out that this library causes problem with native dragging events within every application it is installed in.
So the solution would be using react-dnd that I already have installed in my project.

How to programmatically close bootstrap 5 offcanvas in Next Js

I use using bootstrap 5 in my NextJs app my installing like this:
npm install bootstrap and imported the necessary files into my project via _app.js like this:
import 'bootstrap/dist/css/bootstrap.css'
...
useEffect(() => {
import("bootstrap/dist/js/bootstrap");
}, []);
Now the problem is that when I open the offcanvas modal and click a link from there, the offcanvas stays open after the page changes, instead of closing. How do I programmatically close the offcanvas when the pathname changes and only when the offcanvas is active. Thank you
NB: I am not using react-bootstrap
Import like this:-
useEffect(() => {
import("bootstrap/dist/js/bootstrap.bundle");
}, []);
Recently I ran into the same problem, but here is how I got things working.
First of I do not think you are importing bootstrap in to your nextjs app the right way, but what works work. However I think you should import bootstrap into your nextjs app this way.
useEffect(() => {
typeof document !== undefined
? require("bootstrap/dist/js/bootstrap")
: null;
}, []);
I don't want to make this too long, so lets dive straight into creating the solution. First you have to create a custom function to close the offCanvas when you click your link.
const topicRef = useRef(null);
const closeOffCanvas = (event) => {
event.stopPropagation();
const bootstrap = require("bootstrap/dist/js/bootstrap");
var myOffcanvas = topicRef.current;
var bsOffcanvas = bootstrap.Offcanvas.getInstance(myOffcanvas);
bsOffcanvas.hide();
};
Now create your link like so and call the function we just created
<Link href={`/article/18004/close-bootstrap-5-offcanvas-in-next-js`} passHref>
<a href="#" onClick={closeOffCanvas}>navigate to page then close offCanvas</a>
</Link>
I hope this helps you

Swiperjs in React : swiper.slideTo TypeScript

I am trying to use Swiperjs in my project, in a Typescript file. I want to change the active slide from another component (Tabs, from material UI, already in place). I can swipe directly in the Swiper component but I'd like to make that possible otherwise and elsewhere as well.
However I do not find the way to trigger the method slideTo (here the API) outside the component
...
<Swiper
onSlideChange={(swiper) => setValue(swiper.realIndex)}
...
>
Here my slides, other components, ...
</Swiper>
So ideally I'd rather like to have something like :
...
function handleExternalChangeSlide=(newSlideIndexToShow)=>{
swiper.slidesTo(newSlideIndexToShow)
}
<Swiper
onSlideChange={(swiper) => setValue(swiper.realIndex)}
...
>
Here my slides, other components, ...
</Swiper>
I have seen many people doing that:
var swiper = new Swiper('.swiper-container', {
... options
});
function handleExternalChangeSlide=(newSlideIndexToShow)=>{
swiper.slidesTo(newSlideIndexToShow)
}
)
But actually, Typescript claims that: Only a void function can be called with the 'new' keyword and I do not know how to handle that
Do you see any way to proceed to be able to change the active slide (without using pagination from Swiper) outside Swiper component in my .tsx file?
The Swiper component takes onSwiper props a function that will return you an instance of the created Swiper.
You can save this instance to a state and then call all the methods you need on it.
Here is one of the implementation options:
const [swiperInstance, setSwiperInstance] = useState<SwiperCore>();
const handleExternalChangeSlide = (newSlideIndexToShow) => {
swiperInstance.slidesTo(newSlideIndexToShow);
}
...
<Swiper
onSwiper={setSwiperInstance}
onSlideChange={(swiper) => setValue(swiper.realIndex)}
...
>
Here my slides, other components, ...
</Swiper>

Why does this component render twice in react?

I have a component, I set a count and let state update when button clicked.
But when I check render times, it renders twice each time I click the button.
https://codesandbox.io/s/brave-forest-yre6y?file=/src/App.js
export default function App() {
const cute = Array(10).fill({});
const [count, setCount] = useState(2);
console.log(count);
return (
<div className="App">
<button
onClick={() => {
if (count < 10) setCount(count + 1);
}}
>
add
</button>
{cute.map((data, index) => {
if (index < count) {
return (
<div>
<p>{index}. Luna is cute</p>
</div>
);
}
})}
</div>
);
}
I wonder:
Why does it work like this?
How could I prevent this?
Your app is using StrictMode. See your index.js file - your app is wrapped between a <React.StrictMode> element.
Using StrictMode will cause your app to render twice, but only in development mode. Creating an app with create-react-app will enable strict mode by default.
Here are the official docs for strict mode.
The solution is just to remove <React.StrictMode>, but that will also disable some of its advantages, so if it doesn't bother you, I'd just leave it as is, knowing it won't render like that in production.
See this related question for more details: My React Component is rendering twice because of Strict Mode
Obviously that re-rendering thing is definitely not a bug, or something related with the library's render mechanism. On the contrary it is a debugging mechanism provided by React 🤗
refer this blog https://mariosfakiolas.com/blog/my-react-components-render-twice-and-drive-me-crazy/
you'll get better understanding .
you can disable strictmode refer this sandbox link.it'll only render once .
https://codesandbox.io/s/snowy-violet-eo70o?file=/src/index.js

Resources