Skip to content

Commit

Permalink
fix: fixed stale / wrong states when initializing; Backported from ma…
Browse files Browse the repository at this point in the history
…ster; This version was not affected by the bug but just all versions have the same behaviour now.
  • Loading branch information
BowlingX committed May 6, 2022
1 parent 0b14192 commit e505b69
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 74 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
"zustand": "^3.7.0"
},
"resolutions": {
"react-docgen-typescript": "2.2.2",
"lodash": "4.17.19",
"dot-prop": "5.2.0"
},
Expand Down
64 changes: 8 additions & 56 deletions src/__tests__/defaults.tsx
Original file line number Diff line number Diff line change
@@ -1,73 +1,25 @@
/* tslint:disable:no-expression-statement no-object-mutation */
import { mount } from 'enzyme'
import { createMemoryHistory } from 'history'
import React, {
createContext,
FC,
useCallback,
useContext,
useMemo,
useState
} from 'react'
import Geschichte, { factoryParameters, pm, serializers } from '../index'

const config = {
someParameter: pm('wow', serializers.string)
}
const defaultValues = () => ({
someParameter: 'test'
})

interface Props<T = {}> {
readonly defaultValues: T
}

const defaultProductSearchWithoutCustomization = factoryParameters(
config,
defaultValues
)

const ConfigurableProductSearchContext = createContext(
defaultProductSearchWithoutCustomization
)

const SearchProvider: FC<Props> = ({
defaultValues: thisDefaultValues,
children
}) => {
const value = useMemo(() => {
return factoryParameters(config, () => ({
...defaultValues(),
...thisDefaultValues
}))
}, [thisDefaultValues])

return (
<ConfigurableProductSearchContext.Provider value={value}>
{children}
</ConfigurableProductSearchContext.Provider>
)
}

const useQuery = () => {
const { useQuery: thisUseQuery } = useContext(
ConfigurableProductSearchContext
)
return thisUseQuery()
}
import React, { useCallback, useState } from 'react'
import {
SearchProvider,
useQuery as useDefaultQuery
} from '../examples/defaults'
import Geschichte from '../index'

describe('<Geschichte /> dynamic defaults', () => {
const history = createMemoryHistory()

const ComponentThatDisplaysValue = () => {
const {
values: { someParameter }
} = useQuery()
} = useDefaultQuery()
return <span>{someParameter}</span>
}

const ComponentThatUsesQuery = () => {
const { pushState } = useQuery()
const { pushState } = useDefaultQuery()
return (
<>
<button
Expand Down
54 changes: 54 additions & 0 deletions src/examples/defaults.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { pm } from '../lib/utils'
import { serializers } from '../lib/serializers'
import { factoryParameters } from '../lib/store'
import React, { createContext, FC, useContext, useMemo } from 'react'

const config = {
someParameter: pm('wow', serializers.string)
}
const defaultValues = () => ({
someParameter: 'test'
})

interface Props<T = {}> {
readonly defaultValues: T
}

const defaultProductSearchWithoutCustomization = factoryParameters(
config,
defaultValues,
'some'
)

const ConfigurableProductSearchContext = createContext(
defaultProductSearchWithoutCustomization
)

export const SearchProvider: FC<Props> = ({
defaultValues: thisDefaultValues,
children
}) => {
const value = useMemo(() => {
return factoryParameters(
config,
() => ({
...defaultValues(),
...thisDefaultValues
}),
'some'
)
}, [thisDefaultValues])

return (
<ConfigurableProductSearchContext.Provider value={value}>
{children}
</ConfigurableProductSearchContext.Provider>
)
}

export const useQuery = () => {
const { useQuery: thisUseQuery } = useContext(
ConfigurableProductSearchContext
)
return thisUseQuery()
}
34 changes: 33 additions & 1 deletion src/examples/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* tslint:disable:no-expression-statement no-object-mutation */
import { createBrowserHistory } from 'history'
import React from 'react'
import React, { useCallback, useState } from 'react'
import Geschichte, { factoryParameters, pm, serializers } from '../index'
import { SearchProvider, useQuery as useDefaultableQuery } from './defaults'

const history = createBrowserHistory()

Expand Down Expand Up @@ -65,9 +66,40 @@ const DifferentApp = () => {
)
}

const ComponentThatDisplaysValue = () => {
const {
values: { someParameter },
initialValues
} = useDefaultableQuery()
return (
<div>
Now: {someParameter}, {JSON.stringify(initialValues)}
</div>
)
}

const DefaultValueWrapper = () => {
const [values, setValues] = useState({ someParameter: 'current default' })

const setNewDefaults = useCallback(() => {
setValues({ someParameter: 'new default' })
}, [setValues])

return (
<SearchProvider defaultValues={values}>
<button title="resetDefaults" onClick={setNewDefaults}>
Update defaults
</button>
<ComponentThatDisplaysValue />
<ComponentThatDisplaysValue />
</SearchProvider>
)
}

export const App = () => (
<>
<Geschichte history={history}>
<DefaultValueWrapper />
<h3>A sample Appliations</h3>
<InnerApp />
<DifferentApp />
Expand Down
5 changes: 3 additions & 2 deletions src/lib/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface NamespaceValues<ValueState> {
mappedConfig: MappedConfig
config: Config
query: object
unsubscribe: () => void
unsubscribe: () => boolean
}

export type PushStateFunction<T> = (
Expand All @@ -46,7 +46,7 @@ export interface InnerNamespace<T> {
}

interface RegistryPayload<ValueState> {
unsubscribe: () => void
unsubscribe: () => boolean
values: ValueState
initialValues: ValueState
}
Expand Down Expand Up @@ -413,6 +413,7 @@ export const converter = <T>(historyInstance: HistoryManagement) => (
delete thisState[ns]
}
}, HistoryEventType.REGISTER)
return !get().namespaces[ns]
}
state.mappedConfig = mappedConfig
state.config = config
Expand Down
14 changes: 3 additions & 11 deletions src/lib/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,18 +187,8 @@ export const factoryParameters = <T>(
}),
shallow
)

const initialRegisterState = useMemo(() => {
const namespaceData = useStore.getState().namespaces[ns] || {}
const initialValues = memCreateInitialValues(defaultInitialValues)
const { values, query } = namespaceData
if (values) {
return {
initialValues,
query,
values
}
}
return memInitBlank(initialQueries(), initialValues)
}, [useStore, defaultInitialValues])

Expand All @@ -218,7 +208,9 @@ export const factoryParameters = <T>(
)
if (
initialRegisterState.values !== values ||
initialRegisterState.initialValues !== initialValues
initialRegisterState.initialValues !== initialValues ||
currentState.initialValues !== initialValues ||
currentState.values !== values
) {
setCurrentState({ values, initialValues })
}
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12517,10 +12517,10 @@ react-docgen-typescript-loader@^3.6.0:
loader-utils "^1.2.3"
react-docgen-typescript "^1.15.0"

react-docgen-typescript@^1.15.0:
version "1.16.3"
resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-1.16.3.tgz#f18ba336e51a71b7e4dc17fab39aaaf400114c0c"
integrity sha512-xYISCr8mFKfV15talgpicOF/e0DudTucf1BXzu/HteMF4RM3KsfxXkhWybZC3LTVbYrdbammDV26Z4Yuk+MoWg==
react-docgen-typescript@2.2.2, react-docgen-typescript@^1.15.0:
version "2.2.2"
resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c"
integrity sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==

react-docgen@^5.0.0:
version "5.3.0"
Expand Down

0 comments on commit e505b69

Please sign in to comment.