reactjs - 如何以 react 方式从 mobx observable 获取项目?

标签 reactjs mobx

假设有一个单例 TodosStore,如下所示:

class TodosStore {
    @observable isLoading;
    @observable todos;

    @action.bound fetchTodos() {
        this.isLoading = true;
        return api.getTodos().then(todos => this.todos = todos)
            .finally(()=>this.isLoading=false);
    }

    getTodoById(id) {
        return this.todos.find(todo => todo.id === id);
    }
}

我们还假设有一个使用 URL 表示状态的待办事项详细信息 View ,例如/todos/123

@observer class TodoDetail extends React.Component {
    constructor(props){
        TodosStore.fetchTodos().then(
            this.todo = TodosStore.getTodoById(props.subscriptionId);
        );
    }
    render(){
        return (
            <div>
                {TodosStore.isLoading ?
                    'Loading, please wait...' :
                    <h1>this.todo.text</h1>
                }
            </div>
        );
    }
}

因此,this.todo 显然不是响应式的,因此设置它不会重新运行 render()
一种选择是在 View 代码中创建一个 @observable todo;,但我宁愿将 mobx 助手保留在 View 之外。

请问有更好的方法吗?

最佳答案

一种解决方案

一种方法是使用 React 的 setState 方法。

 constructor(props){
    TodosStore.fetchTodos().then({
        this.setState({ todo: TodosStore.getTodoById(props.subscriptionId) })
    });
}

第二种解决方案

另一种方法是访问(取消引用)组件中的待办事项。这样,当待办事项发生变化时,mobx 就知道该组件需要更新。

class TodoStore {
 @observable todos = []; //initialize your todos as empty array
}

@observer class TodoDetail extends React.Component {
   constructor(props){
      TodosStore.fetchTodos();
   }

   render(){
    const todo = TodoStore.todos.find(todo => todo.id === this.props.subscriptionId);
    return (
        <div>
            {TodosStore.isLoading ?
                'Loading, please wait...' :
                <h1>todo.text</h1>
            }
        </div>
    );
   }
}

在这种情况下,每次待办事项数组发生更改时,组件都会尝试查找待办事项并重新渲染。

为了让 mobx 知道,你的组件需要监听你的 observable 的变化,你必须用这个 observable “做”一些事情。 要么访问 observable 的 prop,要么像本例一样,调用一个方法(这里是 todos.find())

还有第三种解决方案

class TodoStore {
 @observable todos = []; //initialize your todos as empty array
}

@observer class TodoDetail extends React.Component {
   constructor(props){
      TodosStore.fetchTodos();
   }

   render(){
    const todo = TodosStore.getTodoById(props.subscriptionId);
    return (
        <div>
            {TodosStore.isLoading ?
                'Loading, please wait...' :
                <h1>todo.text</h1>
            }
        </div>
    );
   }
}

因为您的组件现在在 render 方法中获取您的待办事项,并且您的组件监听 isLoading 属性上的更改,所以当 isLoading 更改时将调用您的组件。

使用此解决方案,每次 isLoading 更改时,您的组件都会重新呈现。

如您所见,访问可观察对象的方式会产生影响。这取决于您希望组件在什么条件下重新渲染。

关于reactjs - 如何以 react 方式从 mobx observable 获取项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50070956/

相关文章:

css - 如何使用 React 访问 css/scss?

angular - mobx & mobx- Angular : how to update & subscribe to updated value from store?

reactjs - Form.Select 值 onChange 语义 UI React

javascript - 在 React Native 应用程序中获取请求后,MobX 存储未更新

reactjs - 当前未启用对实验性语法 'decorators-legacy' 的支持

css - 样式化 React Bootstrap 下拉按钮 div

reactjs - 单击模式本身时,处理外部单击将关闭。当点击模态之外的任何地方时基本上不应该关闭

javascript - 伪选择器在样式组件中的工作方式与在具有 unicode 字符的 css 中一样吗

javascript - 渲染后无法更新表的数据

reactjs - Mobx makeAutoObservable 没有绑定(bind)这个