craft.js icon indicating copy to clipboard operation
craft.js copied to clipboard

Error occurs when useLayer is called。Prompt: Cannot destroy property 'subscribe' of 'e' as it is undefined

Open hnldlsjzt opened this issue 1 year ago • 2 comments

Describe the bug Whether it's an official demo or one's own project, using useLayer directly will prompt Cannon destroy property 'subscribe' of 'e' as it is undefined import { Layers, useLayer } from '@craftjs/layers';

export cosnt Sidebar = ()=>{ // Prompt: Cannot destroy property 'subscribe' of 'e' as it is undefined // useLayer()

// Prompt: Cannot destroy property 'subscribe' of 'e' as it is undefined const { expanded } = useLayer((layer) => ({ expanded: layer.expanded, })); }

To Reproduce `import { useEditor } from '@craftjs/core'; import { Layers, useLayer } from '@craftjs/layers'; import React, { useState } from 'react'; import styled from 'styled-components';

import { SidebarItem } from './SidebarItem';

import CustomizeIcon from '../../../../public/icons/customize.svg'; import LayerIcon from '../../../../public/icons/layers.svg'; import { Toolbar } from '../../Toolbar';

export const SidebarDiv = styled.div<{ enabled: boolean }>width: 280px; opacity: ${(props) => (props.enabled ? 1 : 0)}; background: #fff; margin-right: ${(props) => (props.enabled ? 0 : -280)}px;;

const CarbonAdsContainer = styled.div` width: 100%; margin-top: auto;

#carbonads * { margin: initial; padding: initial; }

#carbonads { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial, sans-serif;

padding: 10px 0.5rem;
border-top: 1px solid rgb(229 231 235);

}

#carbonads { display: flex; width: 100%; background-color: transparent; z-index: 100; }

#carbonads a { color: inherit; text-decoration: none; }

#carbonads a:hover { color: inherit; }

#carbonads span { position: relative; display: block; overflow: hidden; }

#carbonads .carbon-wrap { display: flex; }

#carbonads .carbon-img { display: flex; align-items: center; margin: 0; line-height: 1; max-width: 30%; }

#carbonads .carbon-img img { display: block; max-width: 100% !important; }

#carbonads .carbon-text { font-size: 12px; padding: 10px; margin-bottom: 16px; line-height: 1.5; text-align: right; color: #333333; font-weight: 400; flex: 1; }

#carbonads .carbon-poweredby { display: block; padding: 6px 8px; text-align: center; text-transform: uppercase; letter-spacing: 0.5px; font-weight: 600; font-size: 9px; line-height: 1; position: absolute; bottom: 0; right: 0; color: #8f8f8f; } `;

const Carbonads = () => { const domRef = React.useRef<HTMLDivElement>(null);

React.useEffect(() => { const { current: dom } = domRef;

if (!dom) {
  return;
}

const script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('async', 'true');

script.setAttribute(
  'src',
  '//cdn.carbonads.com/carbon.js?serve=CEAI453N&placement=craftjsorg'
);
script.setAttribute('id', '_carbonads_js');

dom.appendChild(script);

return () => {
  const ad = dom.querySelector('#carbonads');
  if (ad) {
    dom.removeChild(ad);
  }

  dom.removeChild(script);
};

}, []);

return <CarbonAdsContainer ref={domRef} />; };

export const Sidebar = () => {

const [layersVisible, setLayerVisible] = useState(true); const [toolbarVisible, setToolbarVisible] = useState(true); const { enabled } = useEditor((state) => ({ enabled: state.options.enabled, }));

// Prompt: Cannot destroy property 'subscribe' of 'e' as it is undefined // useLayer()

// Prompt: Cannot destroy property 'subscribe' of 'e' as it is undefined const { expanded } = useLayer((layer) => ({ expanded: layer.expanded, }));

return ( <SidebarDiv enabled={enabled} className="sidebar transition bg-white w-2"> <div className="flex flex-col h-full"> <SidebarItem icon={CustomizeIcon} title="Customize" height={!layersVisible ? 'full' : '55%'} visible={toolbarVisible} onChange={(val) => setToolbarVisible(val)} > <Toolbar /> </SidebarItem> <SidebarItem icon={LayerIcon} title="Layers" height={!toolbarVisible ? 'full' : '45%'} visible={layersVisible} onChange={(val) => setLayerVisible(val)} > <div className=""> <Layers expandRootOnLoad={true} /> </SidebarItem> <Carbonads /> </SidebarDiv> ); }; `

Expected behavior

I originally intended to use useLayer to retrieve layers and customize the unfolding of all layers. Is there any other way to automatically expand all layers when using useLayer with an error message

Screenshots image

Your environment

Software Version(s)
craft.js
"@craftjs/core": "0.2.5",
"@craftjs/layers": "0.2.3",
"@craftjs/utils": "0.2.2",
React react: 18.2.0
TypeScript 4.9.5
Browser chrome 版本 127.0.6533.120(正式版本) (64 位)
npm/Yarn yarn
Operating System windows 11

hnldlsjzt avatar Sep 03 '24 08:09 hnldlsjzt

same issue here

ck6u4dj0 avatar Oct 30 '24 13:10 ck6u4dj0

The useLayer hook internally depends on certain contexts provided by Layer, and these contexts have been initialized with specific values(e.g., renderLayer, expandRootOnLoad). This means that if you use useLayer outside the Layer, it will read from the initial context, which can lead to subsequent errors. What you need to do is specify renderLayer prop.

const Foo = () => {
  const MyLayer = () => {
    useLayer()
    return (
      <>ML_FOO</>
    )
  }

  return (
    <Layers renderLayer={MyLayer}></Layers> // Specify renderLayer  to ensure that MyLayer receives the correct context !!!
  )
}

Joe-Max-LK4Job avatar Jan 22 '25 11:01 Joe-Max-LK4Job