reactjs Material-ui的Switch组件onChange处理程序未触发

rmbxnbpk  于 2023-03-22  发布在  React
关注(0)|答案(8)|浏览(205)

我把一些Switch的es在一个应用程序,他们的工作正常。然后我把开关在另一个应用程序,但他们不工作时,点击。
这两个应用程序使用相同的组件.这里是在一个应用程序中工作:

这是另一个应用程序,不工作:

在第二个应用程序中,onChange处理程序似乎永远不会触发。
两个应用程序中的代码如下所示:

<Switch
  checked={(console.log('checked:', status === 'visible'), status === 'visible')}
  onChange={(e, c) => console.log('event:', e, c)}
/>

在第一个应用程序中,我看到了这些console.log的输出,而在第二个应用程序中,我只看到了checked prop 的初始console.log,但我从未看到任何onChange prop 。
我检查了是否有任何祖先元素有click处理程序,没有发现任何返回false、调用stopPropagation或调用preventDefault的处理程序。
请注意,在gif中,当我单击时,涟漪效果仍然有效,因此单击处理显然仍然有效。
你知道为什么onChange不能发射吗?

**更新!**我用常规的<input type="checkbox">元素替换了开关,效果很好!请看:

在我看来,material-ui的<Switch>组件出了问题。我有预感,有机会我会调查一下:应用程序中可能有多个React单例。我会回来发布更新。

yws3nbqq

yws3nbqq1#

我认为,这是一个奇怪的修复,它对我来说工作顺利.所以,而不是handleChange我使用handleClick.我没有在这里使用事件,相反,我传递一个字符串,这显然是状态的名称或id的情况下数组.

<Switch
    checked={this.state.active}
    onClick={() => this.handleToggle('active')}
    value="active"
    inputProps={{ 'aria-label': 'secondary checkbox' }}
/>

handleToggle = (name: string) => {
    this.setState({ active: !this.state.active });
};

我试过handleChange,但问题仍然存在。我希望这个问题能很快得到解决。

kiayqfof

kiayqfof2#

我在WordPress管理区域的CheckboxSwitch也遇到了同样的问题。
原来,有一个全局CSS规则:

input[type="checkbox"] {
  height: 1rem;
  width: 1rem;
}

不过,单击元素的左上角也可以。
作为一个解决方案,我在我的应用程序根中重置了一些样式。

  • 编辑:* 没关系,我只是把我的整个应用程序到影子DOM.有几个gotchas,我会在这里列出:

1.你必须在shadow DOM中为Material-UI样式的元素提供一个自定义的插入点。一般来说,你必须在shadow DOM之外放置任何东西。
1.你必须在shadow DOM内部和shadow DOM外部(light DOM)加载/链接字体。
1.使用ScopedCssBaseline代替全局复位。
1.对话框必须指定其container属性。
这是我如何设置Material-UI的:

// configure-shadow-dom.js

import { create } from 'jss';
import { jssPreset } from '@material-ui/core/styles';

const shadowHostId = 'my-app-root-id'

export const appRoot = document.createElement('div')
appRoot.setAttribute('id', 'app-root')

const styleInsertionPoint = document.createComment('jss-insertion-point')
export const jss = create({
    ...jssPreset(),
    insertionPoint: styleInsertionPoint,
})

const robotoFontLink = document.createElement('link')
robotoFontLink.setAttribute('rel', 'stylesheet')
robotoFontLink.setAttribute('href', 'https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap')

const shadowHost = document.getElementById(shadowHostId)
shadowHost.attachShadow({ mode: 'open' })

const shadowRoot = shadowHost.shadowRoot
shadowRoot.appendChild(robotoFontLink)
shadowRoot.appendChild(styleInsertionPoint)
shadowRoot.appendChild(appRoot)

// index.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import ScopedCssBaseline from '@material-ui/core/ScopedCssBaseline';
import { StylesProvider } from '@material-ui/core/styles';
import App from './App';
import { jss, appRoot } from './configure-shadow-dom';

ReactDOM.render(
    <React.StrictMode>
        <StylesProvider jss={jss}>
            <ScopedCssBaseline>
                <App />
            </ScopedCssBaseline>
        </StylesProvider>
    </React.StrictMode>,
    appRoot
);
6tqwzwtp

6tqwzwtp3#

在我的例子中,页面中有一个CSS,类似于

.some-component { pointer-events: none; }
.some-component * { pointer-events: auto; }

其中.some-component包含我的material-ui按钮和开关。我不得不手动将pointer-events设置为all(或某个值,我现在不记得了),用于开关内部的元素。
所以,这是一件需要注意的事情:检查pointer-events样式正在执行的操作。

6xfqseft

6xfqseft4#

在Switch组件中,将onChange更改为onClick对我很有效:

<Switch
    checked={this.state.active}
    onClick={() => this.handleToggle('active')}
    value="active"
    inputProps={{ 'aria-label': 'secondary checkbox' }}
/>
wfveoks0

wfveoks05#

仍然遇到类似的问题,从开关获取事件。这里有一个使用内部状态的快速修复(你现在应该使用钩子和功能组件,如果没有,你会错过,但你可以使用setState来做我在这里展示的类组件。

const [switchChecked, setSwitchChecked] = useState(false);

.......

<Switch checked={switchChecked} onChange={() => {setSwitchChecked(!switchChecked);}}/>

你需要在组件的本地状态中有一个switchChecked的值。

2o7dmzc5

2o7dmzc56#

尝试将这个已检查或未检查的参数作为第二个参数传递。

<Switch
    checked={this.state.active}
    onClick={(e,flag) => this.handleToggle('active', flag)}
    value="active"
    inputProps={{ 'aria-label': 'secondary checkbox' }}
/>```
8aqjt8rx

8aqjt8rx7#

问题是你必须从事件中嗅探checked属性:event.target.checked
完整解决方案:

import { Switch } from '@material-ui/core';
import { useState } from 'react';

function App() {
  const [checked, setChecked] = useState(false);

  const switchHandler = (event) => {
    //THIS IS THE SOLUTION - use event.target.checked to get value of switch
    setChecked(event.target.checked);
  };

  return (
    <div>
      <Switch checked={checked} onChange={switchHandler} />
    </div>
  );
}

export default App;
xghobddn

xghobddn8#

在浪费了1个小时之后,我知道switch正在e.target.checked处提供值,单击时会切换(true/false)

const [taxIncluded, setTaxIncluded] =useState(false)
       const taxIncludeChange = (e) => {
    console.log(e.target.checked, 'checked value here (true/false)');
  };
<Switch onChange={taxIncludeChange} value={taxIncluded} color="primary" />

相关问题