[英]Material-UI's TextField validation and onChange event handler don't seem to work as expected
[英]Material-ui's Switch component onChange handler is not firing
我在应用程序中放入了一些Switch
es,它们工作正常。 然后我将开关放在另一个应用程序中,但单击时它们不起作用。
这两个应用程序都使用相同的组件。 它在一个应用程序中工作:
这是另一个应用程序,无法正常工作:
在第二个应用程序中, onChange
处理程序似乎从未触发过。
两个应用程序中的代码如下所示:
<Switch
checked={(console.log('checked:', status === 'visible'), status === 'visible')}
onChange={(e, c) => console.log('event:', e, c)}
/>
在第一个应用程序中,我看到了那些console.log
的 output,而在第二个应用程序中,我只看到了checked
道具的初始console.log
,但我从未看到任何onChange
道具。
我检查了是否有任何祖先元素具有click
处理程序,但没有发现任何返回false
、调用stopPropagation
或调用preventDefault
的元素。
请注意在 gif 中,当我单击时,波纹效果仍然有效,因此单击处理显然仍然有效。
任何想法为什么onChange
可能不会触发?
更新! 我用常规<input type="checkbox">
元素替换了开关,效果很好:请参阅:
在我看来,material-ui 的<Switch>
组件有问题。 我有一种预感,我会在有机会时进行调查:应用程序中可能有多个React
singleton。 我会回来发布更新。
我认为,这是一个奇怪的修复,它对我来说很顺利。 因此,我使用的不是 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,但问题仍然存在。 我希望这会很快得到解决。
我在WordPress 管理区域中的Checkbox
和Switch
遇到了同样的问题。
原来,有这样的全局 CSS规则:
input[type="checkbox"] {
height: 1rem;
width: 1rem;
}
但是,单击元素的左上角有效。
作为解决方案,我在我的应用程序根目录中重置了一些样式。
编辑:没关系,我只是将我的整个应用程序放入shadow DOM 中。 有一些问题,我将在此处列出:
ScopedCssBaseline
而不是全局重置。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
);
事实证明,就我而言,页面中有一个 CSS,类似于
.some-component { pointer-events: none; }
.some-component * { pointer-events: auto; }
其中.some-component
包含我的 material-ui 按钮和开关。 我必须手动将pointer-events
设置为all
(或某个值,我目前不记得)为开关内的元素设置。
所以,要注意一件事:检查pointer-events
样式在做什么。
在 Switch 组件中,将 onChange 更改为 onClick 对我有用:
<Switch
checked={this.state.active}
onClick={() => this.handleToggle('active')}
value="active"
inputProps={{ 'aria-label': 'secondary checkbox' }}
/>
试试这个检查的或未检查的作为第二个参数传递。
<Switch
checked={this.state.active}
onClick={(e,flag) => this.handleToggle('active', flag)}
value="active"
inputProps={{ 'aria-label': 'secondary checkbox' }}
/>```
仍然遇到类似的问题,从交换机获取事件。 这是使用内部状态的快速修复(您现在应该使用钩子和功能组件,如果不是您错过了,但是您可以使用setState
来执行我在类组件中显示的内容。)
const [switchChecked, setSwitchChecked] = useState(false);
......
<Switch checked={switchChecked} onChange={() => {setSwitchChecked(!switchChecked);}}/>
您需要在组件本地状态中为switchChecked
设置一个值。
问题是您必须从事件中嗅探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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.