Я обнаружил ошибку с Material-UI и Mobx, Ошибка: Material-UI: capitalize (string) ожидает строковый аргумент

enter code hereЯ столкнулся с этой ошибкой, когда скопировал компонент реакции с https://material-ui-next.com/demos/snackbars/, а состояние этого компонента управляется 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);

и когда я нажимаю кнопку closeButton, ошибка была выброшена с моей консоли:

 - excuted
 - snackbar.js:18 {store: MyState} "---from snackbar"
 - state.js:58 excuted hidden
 - Error: Material-UI: capitalize(string) expects a string argument.

что-то не так с моим использованием mobx? помогите пожалуйста!


person WEN-JY    schedule 13.04.2018    source источник


Ответы (1)


Mobx обернет все примитивы в объекты. Это единственный способ наблюдать примитивные значения. Поскольку ваш SnackbarState обернут в наблюдаемый объект, также все его потомки обернуты в объект. Итак, вертикальные и горизонтальные строки - это строки, обернутые объектами с помощью mobx. Обычно это не было бы проблемой, но пользовательский интерфейс материала проверяет метод capitalize, если он имеет строковый тип. Это не так, потому что это объект типа (строка, заключенная в объект).

Итак, вам нужно преобразовать наблюдаемое обратно в обычный (не завернутый) объект js.

import { toJS } from 'mobx';

let { vertical, horizontal, open} = toJS(this.context.store.snackbarState);

Имейте в виду, что toJS создает клон вашего объекта. Поэтому, когда вы меняете этот клон, наблюдатели не обновляются.

Дополнительная документация:

person Daniel    schedule 13.04.2018
comment
Я действительно знаю, что вы имеете в виду , но все равно получил ту же ошибку, ничего не изменилось после того, как я добавил код в свой js и использовал let { vertical, horizontal, open} = toJS(this.context.store.snackbarState) - person WEN-JY; 13.04.2018
comment
Лучше всего было бы установить точку останова в методе капитализации из пользовательского интерфейса материала и проверить, какой параметр вызывает это и как выглядит стек вызовов. - person Daniel; 13.04.2018
comment
ну, если обнаружите, где проблема, @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', }; } } вертикальный и горизонтальный не могут быть установлены как "ноль" - person WEN-JY; 14.04.2018
comment
Ах хорошо. Отлично, вы нашли решение! - person Daniel; 14.04.2018