MobX反应应用程序中具有类属性的Typescript错误

时间:2017-11-02 21:15:10

标签: reactjs typescript mobx mobx-react

我不确定这是否与我使用MobX devtools的方式有关,我使用MobX与打字稿结合的方式,或者如果它在MobX Devtools本身中出错。

我的设置是与MobX和TypeScript以及MobX DevTools一起做出反应 - 基于Create React App。该应用程序几乎是10分钟todo引入MobX的复制粘贴发现here应用程序有效,但是一旦我尝试使用DevTools检查我的商店内容,我收到错误:

image

商店的代码如下:

export default class ObservableTodoStore {
    @observable 
    todos: any[] = [];
    @observable 
    pendingRequests: number = 0;

    constructor() {
        autorun(() => console.log(this.report));
    }

    @computed 
    get completedTodosCount() {
        return this.todos.filter(
            (todo: any) => todo.completed === true
        ).length;
    }

    @computed 
    get report() {
        if (this.todos.length === 0) {
            return '<none>';
        }
        return `Next todo: "${this.todos[0].task}". ` +
            `Progress: ${this.completedTodosCount}/${this.todos.length}`;
    }

    @action
    addTodo(task: any) {
        this.todos.push({
            task: task,
            completed: false,
            assignee: null
        });
    }
}

我非常欢迎任何我应该尝试的提示或事项。

编辑: 我应该提一下,商店在index.tsx中初始化并传递给与商店交互的组件:

const store = new ObservableTodoStore();

ReactDOM.render(
    <div>
        <DevTools />
        <App store={store} />
    </div>,
    document.getElementById('root') as HTMLElement
);

最后:

export interface ITodoList { store: any; }

@observer
class TodoList extends Component<ITodoList, {}> {
    render() {
        const store = this.props.store;
        return (
            <div>
                {store.report}
                <ul>
                    {store.todos.map(
                        (todo: any, idx: string) => <TodoView todo={todo} key={idx} />
                    )}
                </ul>
                {store.pendingRequests > 0 ? <div>Loading...</div> : null}
                <Button onClick={this.onNewTodo}>New Todo</Button>
                <small> (double-click a todo to edit)</small>
            </div>
        );
    }

    onNewTodo = () => {
        this.props.store.addTodo(prompt('Enter a new todo:', 'coffee plz'));
    }
}

可能更重要的是:在使用TypeScript时期望商店时,只会弹出错误。当不使用TypeScript时,检查工作完美无瑕。

2 个答案:

答案 0 :(得分:1)

我认为您应该在商店类之后首先实例化您的商店:

export let myStore = new ObservableTodoStore()

然后,您想要访问商店的任何地方:

import {store} from '..pathOfStoreFile..'
store.todos.filter(item => item.completed === true).length

答案 1 :(得分:0)

Haven没有运行你的代码,但我不会将商店作为道具通过,而是像那样写:

export class ObservableTodoStore
{
    @observable
    todos: any[] = [];
    @observable
    pendingRequests: number = 0;

    constructor ()
    {
        autorun( () => console.log( this.report ) );
    }

    @computed
    get completedTodosCount ()
    {
        return this.todos.filter(
            ( todo: any ) => todo.completed === true
        ).length;
    }

    @computed
    get report ()
    {
        if ( this.todos.length === 0 )
        {
            return '<none>';
        }
        return `Next todo: "${ this.todos[ 0 ].task }". ` +
            `Progress: ${ this.completedTodosCount }/${ this.todos.length }`;
    }

    @action
    addTodo ( task: any )
    {
        this.todos.push( {
            task: task,
            completed: false,
            assignee: null
        } );
    }
}
export myStore = new ObservableTodoStore()

......和......

import {myStore} from '..storeFile..'
@observer
class TodoList extends Component<{}, {}> {
    render ()
    {
        return (
            <div>
                { myStore.report }
                <ul>
                    { myStore.todos.map(
                        ( todo: any, idx: string ) => <TodoView todo={ todo } key={ idx } />
                    ) }
                </ul>
                { myStore.pendingRequests > 0 ? <div>Loading...</div> : null }
                <Button onClick={ this.onNewTodo }>New Todo</Button>
                <small> (double-click a todo to edit)</small>
            </div>
        );
    }

    onNewTodo = () =>
    {
        myStore.addTodo( prompt( 'Enter a new todo:', 'coffee plz' ) );
    }
}