为什么我的 React Signals 对话框无法在此处打开?

问题描述 投票:0回答:1

我正在尝试使用信号控制 MUI 对话框,但即使使用 < p >,信号中的值也不会呈现。但是,信号的值在控制台中发生了变化。所以如果我点击 FAB 什么也不会发生。

App.jsx

import Fab from "@mui/material/Fab";
import AddIcon from "@mui/icons-material/Add";
import "./App.css";

import AddItemDialog from "./AddItemDialog";
import { signal } from "@preact/signals-react";

const addItemDialog = signal(false);

function App() {
    console.log("Render App");

    const fabStyle = {
        position: "absolute",
        bottom: 16,
        right: 16,
    };

    function openDialog() {
        addItemDialog.value = true;
    }

    return (
        <>
            <p>{addItemDialog.value}Test</p>
            <AddItemDialog addItemDialog={addItemDialog} />
            <Fab sx={fabStyle} color="primary" onClick={openDialog}>
                <AddIcon />
            </Fab>
        </>
    );
}

export default App;

AddItemDialog.jsx

mport React, { useRef } from "react";
import { Dialog, DialogTitle, DialogContent } from "@mui/material";

export default function AddItemDialog({ addItemDialog }) {
    console.log("Render Dialog");

    const name = useRef();

    function close() {
        addItemDialog.value = false;
    }

    return (
        <Dialog open={addItemDialog.value} onClose={close} fullWidth maxWidth="sm">
            <DialogTitle>Add Item</DialogTitle>
            <DialogContent>
                <input type="text" ref={name} />
            </DialogContent>
        </Dialog>
    );
}

Preview of Website

将信号替换为 useState 可以,但整个应用程序在更改后会重新渲染

编辑: 我通过将两个组件放入另一个组件并使用那里的状态来使其工作,但为什么它不能与信号一起工作?

reactjs material-ui preact preact-signal
1个回答
0
投票

如果您想在 React 应用程序中继续使用 @preact/signals-react 并使 UI 对信号的变化做出反应,您需要以信号值的变化触发 React 组件重新渲染的方式进行集成。一种方法可能是使用自定义挂钩将信号更改与状态更新联系起来,如下所示:

import { useEffect, useState } from 'react';

function useSignal(signal) {
    const [value, setValue] = useState(signal.value);

    useEffect(() => {
        const effect = signal.effect(() => {
            setValue(signal.value);
        });

        return () => effect.dispose();
    }, [signal]);

    return value;
}

// In your component
function App() {
    const dialogOpen = useSignal(addItemDialog);
    // ...
}
© www.soinside.com 2019 - 2024. All rights reserved.