mirror of
https://github.com/langgenius/dify.git
synced 2026-05-06 02:18:08 +08:00
refactor(web): defer state reads to usage point for Zustand stores
Apply "defer state reads to usage point" principle to fix real anti-patterns where state properties were subscribed but only used in callbacks, not in JSX render: - env-panel/variable-modal.tsx: envList, envSecrets -> getState() - chat-variable-panel/variable-modal.tsx: varList -> getState() - publish-as-knowledge-pipeline-modal.tsx: knowledgeName, knowledgeIcon -> lazy useState initialization with getState() - rag-pipeline-header/index.tsx: remove unused showDebugAndPreviewPanel subscription and dead code cleanup
This commit is contained in:
@ -11,7 +11,7 @@ import Button from '@/app/components/base/button'
|
|||||||
import Input from '@/app/components/base/input'
|
import Input from '@/app/components/base/input'
|
||||||
import Modal from '@/app/components/base/modal'
|
import Modal from '@/app/components/base/modal'
|
||||||
import Textarea from '@/app/components/base/textarea'
|
import Textarea from '@/app/components/base/textarea'
|
||||||
import { useStore } from '@/app/components/workflow/store'
|
import { useWorkflowStore } from '@/app/components/workflow/store'
|
||||||
|
|
||||||
type PublishAsKnowledgePipelineModalProps = {
|
type PublishAsKnowledgePipelineModalProps = {
|
||||||
confirmDisabled?: boolean
|
confirmDisabled?: boolean
|
||||||
@ -28,10 +28,9 @@ const PublishAsKnowledgePipelineModal = ({
|
|||||||
onConfirm,
|
onConfirm,
|
||||||
}: PublishAsKnowledgePipelineModalProps) => {
|
}: PublishAsKnowledgePipelineModalProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const knowledgeName = useStore(s => s.knowledgeName)
|
const workflowStore = useWorkflowStore()
|
||||||
const knowledgeIcon = useStore(s => s.knowledgeIcon)
|
const [pipelineName, setPipelineName] = useState(() => workflowStore.getState().knowledgeName!)
|
||||||
const [pipelineName, setPipelineName] = useState(knowledgeName!)
|
const [pipelineIcon, setPipelineIcon] = useState(() => workflowStore.getState().knowledgeIcon!)
|
||||||
const [pipelineIcon, setPipelineIcon] = useState(knowledgeIcon!)
|
|
||||||
const [description, setDescription] = useState('')
|
const [description, setDescription] = useState('')
|
||||||
const [showAppIconPicker, setShowAppIconPicker] = useState(false)
|
const [showAppIconPicker, setShowAppIconPicker] = useState(false)
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import {
|
|||||||
memo,
|
memo,
|
||||||
useMemo,
|
useMemo,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
|
||||||
import Header from '@/app/components/workflow/header'
|
import Header from '@/app/components/workflow/header'
|
||||||
import {
|
import {
|
||||||
useStore,
|
useStore,
|
||||||
@ -13,9 +12,7 @@ import Publisher from './publisher'
|
|||||||
import RunMode from './run-mode'
|
import RunMode from './run-mode'
|
||||||
|
|
||||||
const RagPipelineHeader = () => {
|
const RagPipelineHeader = () => {
|
||||||
const { t } = useTranslation()
|
|
||||||
const pipelineId = useStore(s => s.pipelineId)
|
const pipelineId = useStore(s => s.pipelineId)
|
||||||
const showDebugAndPreviewPanel = useStore(s => s.showDebugAndPreviewPanel)
|
|
||||||
|
|
||||||
const viewHistoryProps = useMemo(() => {
|
const viewHistoryProps = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
@ -42,7 +39,7 @@ const RagPipelineHeader = () => {
|
|||||||
viewHistoryProps,
|
viewHistoryProps,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}, [viewHistoryProps, showDebugAndPreviewPanel, t])
|
}, [viewHistoryProps])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Header {...headerProps} />
|
<Header {...headerProps} />
|
||||||
|
|||||||
@ -22,7 +22,7 @@ import {
|
|||||||
arrayStringPlaceholder,
|
arrayStringPlaceholder,
|
||||||
objectPlaceholder,
|
objectPlaceholder,
|
||||||
} from '@/app/components/workflow/panel/chat-variable-panel/utils'
|
} from '@/app/components/workflow/panel/chat-variable-panel/utils'
|
||||||
import { useStore } from '@/app/components/workflow/store'
|
import { useWorkflowStore } from '@/app/components/workflow/store'
|
||||||
import { cn } from '@/utils/classnames'
|
import { cn } from '@/utils/classnames'
|
||||||
import { checkKeys, replaceSpaceWithUnderscoreInVarNameInput } from '@/utils/var'
|
import { checkKeys, replaceSpaceWithUnderscoreInVarNameInput } from '@/utils/var'
|
||||||
import ArrayBoolList from './array-bool-list'
|
import ArrayBoolList from './array-bool-list'
|
||||||
@ -58,7 +58,7 @@ const ChatVariableModal = ({
|
|||||||
}: ModalPropsType) => {
|
}: ModalPropsType) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { notify } = useContext(ToastContext)
|
const { notify } = useContext(ToastContext)
|
||||||
const varList = useStore(s => s.conversationVariables)
|
const workflowStore = useWorkflowStore()
|
||||||
const [name, setName] = React.useState('')
|
const [name, setName] = React.useState('')
|
||||||
const [type, setType] = React.useState<ChatVarType>(ChatVarType.String)
|
const [type, setType] = React.useState<ChatVarType>(ChatVarType.String)
|
||||||
const [value, setValue] = React.useState<any>()
|
const [value, setValue] = React.useState<any>()
|
||||||
@ -234,6 +234,7 @@ const ChatVariableModal = ({
|
|||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
if (!checkVariableName(name))
|
if (!checkVariableName(name))
|
||||||
return
|
return
|
||||||
|
const varList = workflowStore.getState().conversationVariables
|
||||||
if (!chatVar && varList.some(chatVar => chatVar.name === name))
|
if (!chatVar && varList.some(chatVar => chatVar.name === name))
|
||||||
return notify({ type: 'error', message: 'name is existed' })
|
return notify({ type: 'error', message: 'name is existed' })
|
||||||
// if (type !== ChatVarType.Object && !value)
|
// if (type !== ChatVarType.Object && !value)
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import Button from '@/app/components/base/button'
|
|||||||
import Input from '@/app/components/base/input'
|
import Input from '@/app/components/base/input'
|
||||||
import { ToastContext } from '@/app/components/base/toast'
|
import { ToastContext } from '@/app/components/base/toast'
|
||||||
import Tooltip from '@/app/components/base/tooltip'
|
import Tooltip from '@/app/components/base/tooltip'
|
||||||
import { useStore } from '@/app/components/workflow/store'
|
import { useWorkflowStore } from '@/app/components/workflow/store'
|
||||||
import { cn } from '@/utils/classnames'
|
import { cn } from '@/utils/classnames'
|
||||||
import { checkKeys, replaceSpaceWithUnderscoreInVarNameInput } from '@/utils/var'
|
import { checkKeys, replaceSpaceWithUnderscoreInVarNameInput } from '@/utils/var'
|
||||||
|
|
||||||
@ -25,8 +25,7 @@ const VariableModal = ({
|
|||||||
}: ModalPropsType) => {
|
}: ModalPropsType) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { notify } = useContext(ToastContext)
|
const { notify } = useContext(ToastContext)
|
||||||
const envList = useStore(s => s.environmentVariables)
|
const workflowStore = useWorkflowStore()
|
||||||
const envSecrets = useStore(s => s.envSecrets)
|
|
||||||
const [type, setType] = React.useState<'string' | 'number' | 'secret'>('string')
|
const [type, setType] = React.useState<'string' | 'number' | 'secret'>('string')
|
||||||
const [name, setName] = React.useState('')
|
const [name, setName] = React.useState('')
|
||||||
const [value, setValue] = React.useState<any>()
|
const [value, setValue] = React.useState<any>()
|
||||||
@ -58,6 +57,7 @@ const VariableModal = ({
|
|||||||
return notify({ type: 'error', message: 'value can not be empty' })
|
return notify({ type: 'error', message: 'value can not be empty' })
|
||||||
|
|
||||||
// Add check for duplicate name when editing
|
// Add check for duplicate name when editing
|
||||||
|
const envList = workflowStore.getState().environmentVariables
|
||||||
if (env && env.name !== name && envList.some(e => e.name === name))
|
if (env && env.name !== name && envList.some(e => e.name === name))
|
||||||
return notify({ type: 'error', message: 'name is existed' })
|
return notify({ type: 'error', message: 'name is existed' })
|
||||||
// Original check for create new variable
|
// Original check for create new variable
|
||||||
@ -78,10 +78,11 @@ const VariableModal = ({
|
|||||||
if (env) {
|
if (env) {
|
||||||
setType(env.value_type)
|
setType(env.value_type)
|
||||||
setName(env.name)
|
setName(env.name)
|
||||||
|
const envSecrets = workflowStore.getState().envSecrets
|
||||||
setValue(env.value_type === 'secret' ? envSecrets[env.id] : env.value)
|
setValue(env.value_type === 'secret' ? envSecrets[env.id] : env.value)
|
||||||
setDescription(env.description)
|
setDescription(env.description)
|
||||||
}
|
}
|
||||||
}, [env, envSecrets])
|
}, [env, workflowStore])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
Reference in New Issue
Block a user