React Signals数据无法渲染但useState正常,求技术排查
React Signals数据已更新但无法渲染的排查与解决
核心问题原因
你遇到的情况本质是组件没有正确订阅信号的变化。@preact/signals-react的信号更新触发重渲染,依赖编译转换(Babel/SWC插件)自动追踪信号访问,或者通过直接引用信号实例(而非.value)触发自动解包与订阅。
快速修复方案(无需配置插件)
在JSX中直接使用信号实例,不需要访问.value——Signals会自动在JSX中解包值,同时让组件订阅信号的变化:
// 修改前 <pre> Frontend request Time= {MWDtFeReq.value} </pre> <pre> Middleware request Time= {MWDtMwReq.value} </pre> // 修改后 <pre> Frontend request Time= {MWDtFeReq} </pre> <pre> Middleware request Time= {MWDtMwReq} </pre>
修改后的完整代码:
import { useSignal } from '@preact/signals-react' const FamiliezSysteem = () => { const MWDtFeReq = useSignal(""); const MWDtMwReq = useSignal(""); const handleButtonClickToPingMW = async () => { try { const now = new Date(); const offset = now.getTimezoneOffset() * 60000; const localISOTime = new Date(now - offset).toISOString().slice(0, -1); const url = `http://127.0.0.1:8000/pingAPI?timestampFE=${localISOTime}`; const response = await fetch(url); const data = await response.json(); MWDtFeReq.value = data[0]["FE request time"]; MWDtMwReq.value = data[0]["MW request time"]; } catch (error) { console.error('Error fetching data:', error); } }; return ( <div> <div>Familiez systeem, FTW!</div> <button onClick={handleButtonClickToPingMW}>Ping MiddleWare</button> <pre> Frontend request Time= {MWDtFeReq} </pre> <pre> Middleware request Time= {MWDtMwReq} </pre> </div> ); }; export default FamiliezSysteem;
彻底解决:配置编译转换插件
如果希望在组件逻辑中(比如useEffect或自定义函数)访问.value时也能自动触发重渲染,需要配置对应的编译插件,让React组件自动订阅信号变化。
Create React App 项目
- 安装依赖:
npm install @preact/signals-react-transform craco --save-dev - 项目根目录创建
craco.config.js:module.exports = { babel: { plugins: ['@preact/signals-react-transform'] } }; - 修改
package.json的scripts:"scripts": { "start": "craco start", "build": "craco build", "test": "craco test" }
Vite 项目
- 安装依赖:
npm install @preact/signals-react-transform-vite --save-dev - 修改
vite.config.js:import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import signalsTransform from '@preact/signals-react-transform-vite'; export default defineConfig({ plugins: [signalsTransform(), react()] });
配置完成后,你既可以在JSX中用{MWDtFeReq.value},也能在组件逻辑中访问.value时自动触发重渲染。
内容的提问来源于stack exchange,提问作者Franzl
相关产品推荐
相关产品推荐

