From 0008c9e188a9a97fc67245c0da57e952903693f0 Mon Sep 17 00:00:00 2001 From: 0xYYBB | ZYY | Bobo <128128010+zhouyongyou@users.noreply.github.com> Date: Mon, 10 Nov 2025 11:57:55 +0800 Subject: [PATCH] =?UTF-8?q?fix(web):=20remove=20circular=20dependency=20ca?= =?UTF-8?q?using=20trading=20symbols=20input=20bug=20(#632)=20(#671)=20**P?= =?UTF-8?q?roblem:**=20Unable=20to=20type=20comma-separated=20trading=20sy?= =?UTF-8?q?mbols=20in=20the=20input=20field.=20When=20typing=20"BTCUSDT,"?= =?UTF-8?q?=20=E2=86=92=20comma=20immediately=20disappears=20=E2=86=92=20c?= =?UTF-8?q?annot=20add=20more=20symbols.=20**Root=20Cause:**=20Circular=20?= =?UTF-8?q?state=20dependency=20between=20`useEffect`=20and=20`handleInput?= =?UTF-8?q?Change`:=20```typescript=20//=20=E2=9D=8C=20Lines=20146-149:=20?= =?UTF-8?q?useEffect=20syncs=20selectedCoins=20=E2=86=92=20formData=20useE?= =?UTF-8?q?ffect(()=20=3D>=20{=20=20=20const=20symbolsString=20=3D=20selec?= =?UTF-8?q?tedCoins.join(',')=20=20=20setFormData(prev=20=3D>=20({=20...pr?= =?UTF-8?q?ev,=20trading=5Fsymbols:=20symbolsString=20}))=20},=20[selected?= =?UTF-8?q?Coins])=20//=20Lines=20150-153:=20handleInputChange=20syncs=20f?= =?UTF-8?q?ormData=20=E2=86=92=20selectedCoins=20if=20(field=20=3D=3D=3D?= =?UTF-8?q?=20'trading=5Fsymbols')=20{=20=20=20const=20coins=20=3D=20value?= =?UTF-8?q?.split(',').map(...).filter(...)=20=20=20setSelectedCoins(coins?= =?UTF-8?q?)=20}=20```=20**Execution=20Flow:**=201.=20User=20types:=20`"BT?= =?UTF-8?q?CUSDT,"`=202.=20`handleInputChange`=20fires=20=E2=86=92=20split?= =?UTF-8?q?s=20by=20comma=20=E2=86=92=20filters=20empty=20=E2=86=92=20`sel?= =?UTF-8?q?ectedCoins=20=3D=20["BTCUSDT"]`=203.=20`useEffect`=20fires=20?= =?UTF-8?q?=E2=86=92=20joins=20=E2=86=92=20overwrites=20input=20to=20`"BTC?= =?UTF-8?q?USDT"`=20=E2=9D=8C=20**Trailing=20comma=20removed!**=204.=20Use?= =?UTF-8?q?r=20cannot=20continue=20typing=20**Solution:**=20Remove=20the?= =?UTF-8?q?=20redundant=20`useEffect`=20(lines=20146-149)=20and=20update?= =?UTF-8?q?=20`handleCoinToggle`=20to=20directly=20sync=20both=20states:?= =?UTF-8?q?=20```typescript=20//=20=E2=9C=85=20handleCoinToggle=20now=20up?= =?UTF-8?q?dates=20both=20states=20const=20handleCoinToggle=20=3D=20(coin:?= =?UTF-8?q?=20string)=20=3D>=20{=20=20=20setSelectedCoins(prev=20=3D>=20{?= =?UTF-8?q?=20=20=20=20=20const=20newCoins=20=3D=20prev.includes(coin)=20?= =?UTF-8?q?=3F=20...=20:=20...=20=20=20=20=20//=20Directly=20update=20form?= =?UTF-8?q?Data.trading=5Fsymbols=20=20=20=20=20const=20symbolsString=20?= =?UTF-8?q?=3D=20newCoins.join(',')=20=20=20=20=20setFormData(current=20?= =?UTF-8?q?=3D>=20({=20...current,=20trading=5Fsymbols:=20symbolsString=20?= =?UTF-8?q?}))=20=20=20=20=20return=20newCoins=20=20=20})=20}=20```=20**Wh?= =?UTF-8?q?y=20This=20Works:**=20-=20**Quick=20selector=20buttons**=20(`ha?= =?UTF-8?q?ndleCoinToggle`):=20Now=20updates=20both=20states=20=E2=9C=85?= =?UTF-8?q?=20-=20**Manual=20input**=20(`handleInputChange`):=20Already=20?= =?UTF-8?q?updates=20both=20states=20=E2=9C=85=20-=20**No=20useEffect=20in?= =?UTF-8?q?terference**:=20User=20can=20type=20freely=20=E2=9C=85=20**Impa?= =?UTF-8?q?ct:**=20-=20=E2=9C=85=20Manual=20typing=20of=20comma-separated?= =?UTF-8?q?=20symbols=20now=20works=20-=20=E2=9C=85=20Quick=20selector=20b?= =?UTF-8?q?uttons=20still=20work=20correctly=20-=20=E2=9C=85=20No=20circul?= =?UTF-8?q?ar=20dependency=20-=20=E2=9C=85=20Cleaner=20unidirectional=20da?= =?UTF-8?q?ta=20flow=20Fixes=20#632=20Co-authored-by:=20tinkle-community?= =?UTF-8?q?=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/TraderConfigModal.tsx | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/web/src/components/TraderConfigModal.tsx b/web/src/components/TraderConfigModal.tsx index 183f8fbb..9adcec58 100644 --- a/web/src/components/TraderConfigModal.tsx +++ b/web/src/components/TraderConfigModal.tsx @@ -153,12 +153,6 @@ export function TraderConfigModal({ fetchPromptTemplates() }, []) - // 当选择的币种改变时,更新输入框 - useEffect(() => { - const symbolsString = selectedCoins.join(',') - setFormData((prev) => ({ ...prev, trading_symbols: symbolsString })) - }, [selectedCoins]) - if (!isOpen) return null const handleInputChange = (field: keyof TraderConfigData, value: any) => { @@ -176,11 +170,15 @@ export function TraderConfigModal({ const handleCoinToggle = (coin: string) => { setSelectedCoins((prev) => { - if (prev.includes(coin)) { - return prev.filter((c) => c !== coin) - } else { - return [...prev, coin] - } + const newCoins = prev.includes(coin) + ? prev.filter((c) => c !== coin) + : [...prev, coin] + + // 同时更新 formData.trading_symbols + const symbolsString = newCoins.join(',') + setFormData((current) => ({ ...current, trading_symbols: symbolsString })) + + return newCoins }) }