I meet an error with Material-UI and Mobx ,Error: Material-UI: capitalize(string) expects a string argument
I meet an error with Material-UI and Mobx ,Error: Material-UI: capitalize(string) expects a string argument
enter code here
我从 https://material-ui-next.com/demos/snackbars/ 复制一个 React 组件时遇到这个错误
该组件的状态由 Mobx 管理,如下所示:
@observable snackbarState = {
open: false,
vertical: null,
horizontal: null,
};
@action toggleSnackState(){
if(this.snackbarState.vertical){
console.log('excuted','hidden')
this.snackbarState={
open: false,
vertical: null,
horizontal: null,
};
}else{
console.log('excuted')
this.snackbarState={
open: true,
vertical: 'top',
horizontal: 'center',
};
}
}
这是我的 snackbar.js:
import React,{Component} from 'react';
import PropTypes from 'prop-types';
import {PropTypes as MobxPropTypes} from 'mobx-react';
import { withStyles } from 'material-ui/styles';
import Snackbar from 'material-ui/Snackbar';
import IconButton from 'material-ui/IconButton';
import CloseIcon from '@material-ui/icons/Close';
import {observer} from 'mobx-react'
const styles = theme => ({
close: {
width: theme.spacing.unit * 4,
height: theme.spacing.unit * 4,
},
});
@observer
class SimpleSnackbar extends Component {
handleClose=()=>{
console.log(this.context,'---from snackbar')
this.context.store.toggleSnackState();
}
render() {
const { classes } = this.props;
let { vertical, horizontal ,open} = this.context.store.snackbarState;
return (
<div>
<Snackbar
anchorOrigin={{ vertical, horizontal }}
open={open}
autoHideDuration={6000}
onClose={this.handleClose}
SnackbarContentProps={{
'aria-describedby': 'message-id',
}}
message={<span id="message-id">这里是消息内容</span>}
action={[
<IconButton
key="close"
aria-label="Close"
color="inherit"
className={classes.close}
onClick={this.handleClose}
>
<CloseIcon />
</IconButton>,
]}
/>
</div>
);
}
}
SimpleSnackbar.contextTypes={
store:MobxPropTypes.observableObject.isRequired
}
SimpleSnackbar.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(SimpleSnackbar);
当我点击关闭按钮时,控制台抛出错误:
- excuted
- snackbar.js:18 {store: MyState} "---from snackbar"
- state.js:58 excuted hidden
- Error: Material-UI: capitalize(string) expects a string argument.
我使用 mobx 有什么问题吗?请帮忙!
Mobx 将包装对象中的所有原语。这是它可以观察原始值的唯一方法。因为您的 snackbarState 被包裹在一个可观察对象中,所以它的所有后代也被包裹在一个对象中。所以vertical和horizontal是mobx包裹在对象里的字符串。通常这不会成为问题,但是 material ui 检查 capitalize 方法,如果它是字符串类型的话。不是,因为它是对象类型(包裹在对象中的字符串)。
因此您需要将可观察对象转换回普通(非包装)js 对象。
import { toJS } from 'mobx';
let { vertical, horizontal, open} = toJS(this.context.store.snackbarState);
请记住,toJS 会创建对象的克隆。因此,当您更改此克隆时,观察者将不会更新。
更多文档:
enter code here
我从 https://material-ui-next.com/demos/snackbars/ 复制一个 React 组件时遇到这个错误
该组件的状态由 Mobx 管理,如下所示:
@observable snackbarState = {
open: false,
vertical: null,
horizontal: null,
};
@action toggleSnackState(){
if(this.snackbarState.vertical){
console.log('excuted','hidden')
this.snackbarState={
open: false,
vertical: null,
horizontal: null,
};
}else{
console.log('excuted')
this.snackbarState={
open: true,
vertical: 'top',
horizontal: 'center',
};
}
}
这是我的 snackbar.js:
import React,{Component} from 'react';
import PropTypes from 'prop-types';
import {PropTypes as MobxPropTypes} from 'mobx-react';
import { withStyles } from 'material-ui/styles';
import Snackbar from 'material-ui/Snackbar';
import IconButton from 'material-ui/IconButton';
import CloseIcon from '@material-ui/icons/Close';
import {observer} from 'mobx-react'
const styles = theme => ({
close: {
width: theme.spacing.unit * 4,
height: theme.spacing.unit * 4,
},
});
@observer
class SimpleSnackbar extends Component {
handleClose=()=>{
console.log(this.context,'---from snackbar')
this.context.store.toggleSnackState();
}
render() {
const { classes } = this.props;
let { vertical, horizontal ,open} = this.context.store.snackbarState;
return (
<div>
<Snackbar
anchorOrigin={{ vertical, horizontal }}
open={open}
autoHideDuration={6000}
onClose={this.handleClose}
SnackbarContentProps={{
'aria-describedby': 'message-id',
}}
message={<span id="message-id">这里是消息内容</span>}
action={[
<IconButton
key="close"
aria-label="Close"
color="inherit"
className={classes.close}
onClick={this.handleClose}
>
<CloseIcon />
</IconButton>,
]}
/>
</div>
);
}
}
SimpleSnackbar.contextTypes={
store:MobxPropTypes.observableObject.isRequired
}
SimpleSnackbar.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(SimpleSnackbar);
当我点击关闭按钮时,控制台抛出错误:
- excuted
- snackbar.js:18 {store: MyState} "---from snackbar"
- state.js:58 excuted hidden
- Error: Material-UI: capitalize(string) expects a string argument.
我使用 mobx 有什么问题吗?请帮忙!
Mobx 将包装对象中的所有原语。这是它可以观察原始值的唯一方法。因为您的 snackbarState 被包裹在一个可观察对象中,所以它的所有后代也被包裹在一个对象中。所以vertical和horizontal是mobx包裹在对象里的字符串。通常这不会成为问题,但是 material ui 检查 capitalize 方法,如果它是字符串类型的话。不是,因为它是对象类型(包裹在对象中的字符串)。
因此您需要将可观察对象转换回普通(非包装)js 对象。
import { toJS } from 'mobx';
let { vertical, horizontal, open} = toJS(this.context.store.snackbarState);
请记住,toJS 会创建对象的克隆。因此,当您更改此克隆时,观察者将不会更新。
更多文档: