Example usage with Next.js
optimistiks opened this issue · comments
The suggested approach (to use next/dynamic
) did not work for me. I could not use Allotment.Pane
after dynamically importing with ssr:false
, neither from allotment
directly nor from an intermediate component file.
But I got it to work using combination of plain import
and useEffect
just fine.
https://codesandbox.io/s/nextjs-typescript-allotment-c7yvk?file=/components/Panes.tsx
Hi @optimistiks. Thanks for the feedback 🙏.
I'll take a look, make sure I understand what's going on, then add this to the documentation.
To add, the suggested approach using next/dynamic
in the other issue is incorrect. As per this comment from a Next maintainer, next/dynamic
is only used to import components.
The library is now being successfully used in several NextJS projects. I will check what the status is.
Any updates on this? I'm trying with NextJS 13 but I don't get the blue bars rendered on hover. It looks like its SSRing and showing the smallest possible container size.
The library is now being successfully used in several NextJS projects. I will check what the status is.
Would you be so kind to link a working example? I am not able to make the Panes work, nor register a ref successfully with Next12 and React 18.
the ref.current
returns and object with the retry
function only
Based on the linked code sandbox, I created this hook, it works but has an issue.
It produces a warning
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
If you have a fix for it, please post it (probably forwardRef
or convert default state to class-based components), if you don't care feel free to use it. 😄
import { ComponentType, Ref, useEffect, useRef, useState } from "react";
import { AllotmentHandle, AllotmentProps, PaneProps } from "allotment/dist/types/src/allotment";
function useAllotment() {
const isMountedRef = useRef(false);
const allotmentRef = useRef<AllotmentHandle>({
resize: (sizes = [0, 0]) => {
console.warn("Allotment is not mounted yet", sizes);
},
reset: () => {},
});
const [Allotment, setAllotment] = useState<
ComponentType<AllotmentProps & { ref?: Ref<AllotmentHandle> }> & {
Pane: ComponentType<PaneProps>;
}
>(
() => {
function Allotment({ children }: AllotmentProps) {
return <>{children}</>;
}
Allotment.Pane = function ({ children }: PaneProps) {
return <>{children}</>;
};
return Allotment;
},
);
useEffect(() => {
isMountedRef.current = true;
import("allotment")
.then(mod => {
if (!isMountedRef.current) {
return;
}
setAllotment(mod.Allotment);
})
.catch(err => console.error(err, `could not import allotment ${err.message}`));
return () => {
isMountedRef.current = false;
};
}, []);
return { allotmentRef, Allotment };
}
export default useAllotment;
I can confirm I got allotment working with my Next.JS v13 app
I did need to use the dynamic export
Here is what I did...
@/app/components/allotment.component.tsx
export default function AllotmentCmp() {
return (
<Allotment>
<div></div>
<div></div>
</Allotment>
)
}
@/app/components/app.tsx
export const AllotmentCmp = dynamic(
() => import('@/app/components/allotment.component'),
{ ssr: false }
)
function App(){
return (
<AllotmentCmp/>
)
}