Fix the recursion issue with theatric
This commit is contained in:
parent
97ab020bfb
commit
00bb2d3310
2 changed files with 33 additions and 9 deletions
|
@ -1,4 +1,4 @@
|
||||||
import {button, initialize, useControls} from 'theatric'
|
import {button, initialize, types, useControls} from 'theatric'
|
||||||
import {render} from 'react-dom'
|
import {render} from 'react-dom'
|
||||||
import React, {useState} from 'react'
|
import React, {useState} from 'react'
|
||||||
import state from './state.json'
|
import state from './state.json'
|
||||||
|
@ -32,11 +32,12 @@ function App() {
|
||||||
baz: button(() => console.log($get((p) => p.bar))),
|
baz: button(() => console.log($get((p) => p.bar))),
|
||||||
})
|
})
|
||||||
|
|
||||||
const {another, panel, yo} = useControls(
|
const {another, panel, col, yo} = useControls(
|
||||||
{
|
{
|
||||||
another: '',
|
another: '',
|
||||||
panel: '',
|
panel: '',
|
||||||
yo: 0,
|
yo: types.number(0),
|
||||||
|
col: types.rgba(),
|
||||||
},
|
},
|
||||||
{panel: 'My panel'},
|
{panel: 'My panel'},
|
||||||
)
|
)
|
||||||
|
@ -54,7 +55,7 @@ function App() {
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div>{JSON.stringify(bar)}</div>
|
{/* <div>{JSON.stringify(bar)}</div> */}
|
||||||
<SomeComponent id="first" />
|
<SomeComponent id="first" />
|
||||||
<SomeComponent id="second" />
|
<SomeComponent id="second" />
|
||||||
<button
|
<button
|
||||||
|
@ -73,6 +74,7 @@ function App() {
|
||||||
</button>
|
</button>
|
||||||
{showComponent && <SomeComponent id="hidden" />}
|
{showComponent && <SomeComponent id="hidden" />}
|
||||||
{yo}
|
{yo}
|
||||||
|
{JSON.stringify(col)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {getProject} from '@theatre/core'
|
||||||
import type {Pointer} from '@theatre/dataverse'
|
import type {Pointer} from '@theatre/dataverse'
|
||||||
import {isPointer} from '@theatre/dataverse'
|
import {isPointer} from '@theatre/dataverse'
|
||||||
import studio from '@theatre/studio'
|
import studio from '@theatre/studio'
|
||||||
|
import isEqualWith from 'lodash-es/isEqualWith'
|
||||||
import isEqual from 'lodash-es/isEqual'
|
import isEqual from 'lodash-es/isEqual'
|
||||||
import {useEffect, useMemo, useState, useRef} from 'react'
|
import {useEffect, useMemo, useState, useRef} from 'react'
|
||||||
|
|
||||||
|
@ -33,6 +34,17 @@ const maybeTransaction =
|
||||||
|
|
||||||
let _projectConfig: IProjectConfig['state'] | undefined = undefined
|
let _projectConfig: IProjectConfig['state'] | undefined = undefined
|
||||||
|
|
||||||
|
// used for comparing config objects, to avoid re-rendering when the config object is recreated
|
||||||
|
// but the values are the same except for functions
|
||||||
|
function equalityCheckWithFunctionsAlwaysEqual(
|
||||||
|
a: unknown,
|
||||||
|
b: unknown,
|
||||||
|
): boolean | undefined {
|
||||||
|
if (typeof a === 'function' && typeof b === 'function') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function initialize(config: IProjectConfig) {
|
export function initialize(config: IProjectConfig) {
|
||||||
if (_projectConfig !== undefined) {
|
if (_projectConfig !== undefined) {
|
||||||
console.warn(
|
console.warn(
|
||||||
|
@ -100,12 +112,20 @@ export function useControls<Config extends ControlsAndButtons>(
|
||||||
*/
|
*/
|
||||||
const configRef = useRef(config)
|
const configRef = useRef(config)
|
||||||
const _config = useMemo(() => {
|
const _config = useMemo(() => {
|
||||||
if (isEqual(config, configRef.current)) {
|
let currentConfig = configRef.current
|
||||||
return configRef.current
|
|
||||||
} else {
|
if (
|
||||||
|
!isEqualWith(
|
||||||
|
config,
|
||||||
|
configRef.current,
|
||||||
|
equalityCheckWithFunctionsAlwaysEqual,
|
||||||
|
)
|
||||||
|
) {
|
||||||
configRef.current = config
|
configRef.current = config
|
||||||
return config
|
currentConfig = config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return currentConfig
|
||||||
}, [config])
|
}, [config])
|
||||||
|
|
||||||
const {folder} = options
|
const {folder} = options
|
||||||
|
@ -142,7 +162,9 @@ export function useControls<Config extends ControlsAndButtons>(
|
||||||
Object.entries(buttons).map(([key, value]) => [
|
Object.entries(buttons).map(([key, value]) => [
|
||||||
`${folder ? `${folder}: ` : ''}${key}`,
|
`${folder ? `${folder}: ` : ''}${key}`,
|
||||||
() => {
|
() => {
|
||||||
value.onClick()
|
// the value of the button is a function, so we can't use it as a dependency, but we can use it as a ref
|
||||||
|
// @ts-ignore
|
||||||
|
configRef.current[key].onClick?.()
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue