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

时间:2019-01-17 23:54:31

标签: reactjs typescript material-ui

我已经在应用程序中放置了Switch个字符,它们工作正常。然后,我将开关放在另一个应用程序中,但单击后它们不起作用。

两个应用程序都使用相同的组件。在这里,它可以在一个应用程序中运行:

enter image description here

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

enter image description here

在第二个应用程序中,onChange处理程序似乎从未触发过。

两个应用程序中的代码如下:

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

在第一个应用程序中,我看到了这些console.log的输出,而在第二个应用程序中,我仅看到了console.log道具的首个checked,但是我从没看到任何onChange道具。

我检查了是否有任何祖先元素具有click处理函数,但没有找到任何返回false,调用stopPropagation或调用preventDefault的元素。

请注意,当我单击gif时,波纹效果仍然有效,因此单击处理显然仍在起作用。

有什么想法可能无法触发onChange

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

enter image description here

在我看来,material-ui的<Switch>组件有问题。我有一种直觉可以在有机会时进行调查:应用程序中可能有多个React单身人士。我会回去发布更新。

4 个答案:

答案 0 :(得分:0)

我认为,这是一个奇怪的解决方法,它对我来说运行顺利。因此,我不是使用handleChange而是使用handleClick。我不在这里使用事件,而是传递一个字符串,该字符串显然是状态名称或ID(在使用数组的情况下)的名称。

ball[0] = sphere(pos=vector(-1,4,9))
ball[1] = sphere(pos=vector(-2,6,6))
ball[2] = sphere(pos=vector(0,6,1))

我尝试了handleChange,但是问题仍然存在。我希望这个问题能尽快解决。

答案 1 :(得分:0)

事实证明,在我的情况下,页面中有CSS,类似

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

其中.some-component包含我的material-ui按钮和开关。对于开关中的元素,我不得不手动将pointer-events设置为all(或一些值,目前我不记得了)。

所以,这是需要注意的一件事:检查pointer-events样式在做什么。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

WordPress管理员区域中,CheckboxSwitch遇到了同样的问题。

结果是,存在全局CSS 规则,例如:

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

不过,单击元素的左上角是可行的。

作为解决方案,我在应用程序根目录中重置了一些样式。

编辑:没关系,我只是将整个应用程序放入阴影DOM 中。有一些陷阱,我在这里列出:

  1. 您必须为影子DOM中的Material-UI样式元素提供custom insertion point。通常,您必须使影子DOM之外没有任何东西。
  2. 您必须在阴影DOM内部和阴影DOM(浅色DOM)外部加载/链接字体。
  3. 使用ScopedCssBaseline代替全局重置。
  4. 对话框必须指定其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
);