fix(swagger-ui-react): re-render on spec prop change (#9966)

Refs #9965
This commit is contained in:
Oliwia Rogala
2024-05-27 13:06:07 +02:00
committed by GitHub
parent e57d0bed36
commit df03a8f99c

View File

@@ -3,12 +3,20 @@
*/ */
"use client" "use client"
import React, { useEffect, useState } from "react" import React, { useEffect, useRef, useState } from "react"
import PropTypes from "prop-types" import PropTypes from "prop-types"
import SwaggerUIConstructor from "#swagger-ui" import SwaggerUIConstructor from "#swagger-ui"
const { config } = SwaggerUIConstructor const { config } = SwaggerUIConstructor
const usePrevious = (value) => {
const ref = useRef()
useEffect(() => {
ref.current = value
}, [value])
return ref.current
}
const SwaggerUI = ({ const SwaggerUI = ({
spec = config.defaults.spec, spec = config.defaults.spec,
url = config.defaults.url, url = config.defaults.url,
@@ -40,6 +48,8 @@ const SwaggerUI = ({
}) => { }) => {
const [system, setSystem] = useState(null) const [system, setSystem] = useState(null)
const SwaggerUIComponent = system?.getComponent("App", "root") const SwaggerUIComponent = system?.getComponent("App", "root")
const prevSpec = usePrevious(spec)
const prevUrl = usePrevious(url)
useEffect(() => { useEffect(() => {
const systemInstance = SwaggerUIConstructor({ const systemInstance = SwaggerUIConstructor({
@@ -84,22 +94,30 @@ const SwaggerUI = ({
useEffect(() => { useEffect(() => {
if (system) { if (system) {
const prevStateUrl = system.specSelectors.url() const prevStateUrl = system.specSelectors.url()
if (url !== prevStateUrl) { if (url !== prevStateUrl || url !== prevUrl) {
system.specActions.updateSpec("") system.specActions.updateSpec("")
if (url) { if (url) {
system.specActions.updateUrl(url) system.specActions.updateUrl(url)
system.specActions.download(url) system.specActions.download(url)
} }
} }
}
}, [system, url])
useEffect(() => {
if (system) {
const prevStateSpec = system.specSelectors.specStr() const prevStateSpec = system.specSelectors.specStr()
if (spec && spec !== prevStateSpec) { if (
spec &&
spec !== SwaggerUIConstructor.config.defaults.spec &&
(spec !== prevStateSpec || spec !== prevSpec)
) {
const updatedSpec = const updatedSpec =
typeof spec === "object" ? JSON.stringify(spec) : spec typeof spec === "object" ? JSON.stringify(spec) : spec
system.specActions.updateSpec(updatedSpec) system.specActions.updateSpec(updatedSpec)
} }
} }
}, [system, url, spec]) }, [system, spec])
return SwaggerUIComponent ? <SwaggerUIComponent /> : null return SwaggerUIComponent ? <SwaggerUIComponent /> : null
} }