Fix: Re-render the panels when object identity change
This fixes the pesky "Argument 'der' in 'useDerivation(der)' should not change between renders."
This commit is contained in:
parent
4596c2233c
commit
c58bc694ee
5 changed files with 32 additions and 4 deletions
|
@ -40,6 +40,9 @@ const createEditable = <Keys extends keyof JSX.IntrinsicElements>(
|
|||
)
|
||||
}
|
||||
|
||||
// TODO: detect if `editable()` is being called in the body of a react component, which is a common
|
||||
// mistake. If it is, throw an error.
|
||||
|
||||
return forwardRef(
|
||||
(
|
||||
{
|
||||
|
|
16
theatre/shared/src/utils/uniqueKeyForAnyObject.ts
Normal file
16
theatre/shared/src/utils/uniqueKeyForAnyObject.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
const cache = new WeakMap<object, string>()
|
||||
let nextKey = 0
|
||||
|
||||
/**
|
||||
* This function returns a unique string key for any JS object. This is useful for key-ing react components
|
||||
* based on the identity of an object.
|
||||
*
|
||||
* @param obj - any JS object
|
||||
* @returns a unique string key for the object
|
||||
*/
|
||||
export default function uniqueKeyForAnyObject(obj: object): string {
|
||||
if (!cache.has(obj)) {
|
||||
cache.set(obj, (nextKey++).toString())
|
||||
}
|
||||
return cache.get(obj)!
|
||||
}
|
|
@ -118,6 +118,7 @@ const DetailPanel: React.FC<{}> = (props) => {
|
|||
const selection = getOutlineSelection()
|
||||
|
||||
const obj = selection.find(isSheetObject)
|
||||
|
||||
if (obj) {
|
||||
return (
|
||||
<Container
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
import React, {useMemo} from 'react'
|
||||
import React from 'react'
|
||||
import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
|
||||
import type {Pointer} from '@theatre/dataverse'
|
||||
import type {$FixMe} from '@theatre/shared/utils/types'
|
||||
import DeterminePropEditorForDetail from './DeterminePropEditorForDetail'
|
||||
import {useVal} from '@theatre/react'
|
||||
import uniqueKeyForAnyObject from '@theatre/shared/utils/uniqueKeyForAnyObject'
|
||||
|
||||
const ObjectDetails: React.FC<{
|
||||
/** TODO: add support for multiple objects (it would show their common props) */
|
||||
objects: [SheetObject]
|
||||
}> = ({objects}) => {
|
||||
const obj = objects[0]
|
||||
const key = useMemo(() => JSON.stringify(obj.address), [obj])
|
||||
const config = useVal(obj.template.configPointer)
|
||||
|
||||
return (
|
||||
<DeterminePropEditorForDetail
|
||||
key={key}
|
||||
// we don't use the object's address as the key because if a user calls `sheet.detachObject(key)` and later
|
||||
// calls `sheet.object(key)` with the same key, we want to re-render the object details panel.
|
||||
key={uniqueKeyForAnyObject(obj)}
|
||||
obj={obj}
|
||||
pointerToProp={obj.propsP as Pointer<$FixMe>}
|
||||
propConfig={config}
|
||||
|
|
|
@ -4,6 +4,7 @@ import React from 'react'
|
|||
import LeftSheetObjectRow from './SheetObjectRow'
|
||||
import AnyCompositeRow from './AnyCompositeRow'
|
||||
import {setCollapsedSheetItem} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/setCollapsedSheetObjectOrCompoundProp'
|
||||
import uniqueKeyForAnyObject from '@theatre/shared/utils/uniqueKeyForAnyObject'
|
||||
|
||||
const SheetRow: React.VFC<{
|
||||
leaf: SequenceEditorTree_Sheet
|
||||
|
@ -23,7 +24,12 @@ const SheetRow: React.VFC<{
|
|||
>
|
||||
{leaf.children.map((sheetObjectLeaf) => (
|
||||
<LeftSheetObjectRow
|
||||
key={'sheetObject-' + sheetObjectLeaf.sheetObject.address.objectKey}
|
||||
key={
|
||||
'sheetObject-' +
|
||||
// we don't use the object's address as the key because if a user calls `sheet.detachObject(key)` and later
|
||||
// calls `sheet.object(key)` with the same key, we want to re-render this row.
|
||||
uniqueKeyForAnyObject(sheetObjectLeaf.sheetObject)
|
||||
}
|
||||
leaf={sheetObjectLeaf}
|
||||
/>
|
||||
))}
|
||||
|
|
Loading…
Reference in a new issue