从MobX Action计算值:FreeCodeCamp仓库重构的StudentCount问题
解决MobX中在StudentModal组件计算studentCount的问题
看起来你正在用MobX重构FreeCodeCamp的代码,想要在StudentModal组件里基于store的studentCount计算显示文本对吧?我来帮你梳理下正确的实现方式,先从你代码里的几个关键点说起:
1. 先修复Store注入的问题
你现在在组件里new this.props.StudentModal()来创建store实例,这其实是个误区——MobX的@inject是用来获取已经通过Provider全局提供的单例store,而不是让你在组件里实例化新的store。这样做会导致每个组件实例都有自己的store,状态完全不共享,肯定不是你想要的。
正确的做法是:先在你的store文件里创建单例,然后通过Provider注入到组件树,再用@inject获取。
2. 在Store里定义Computed值(如果studentCount是衍生值)
如果studentCount是基于其他数据(比如学生数组长度)计算出来的,那应该在Store里用@computed来定义它,这样MobX会自动追踪依赖,当数据源变化时自动更新这个值:
// 比如你的StudentModalStore.js文件 import { observable, computed, action } from 'mobx'; class StudentModalStore { // 假设你有一个存储学生数据的observable数组 @observable students = []; // 用@computed定义衍生的studentCount @computed get studentCount() { return this.students.length; } // 示例action:添加学生,触发studentCount更新 @action addStudent(student) { this.students.push(student); } } // 导出单例,确保整个应用共用同一个store实例 export default new StudentModalStore();
3. 修正StudentModal组件的实现
现在修改你的Modal.js,直接使用注入的store,不需要自己实例化:
import React, { Component } from 'react'; import { observer, inject } from 'mobx-react'; // 注意这里注入的名称要和Provider里的一致 @inject('studentModalStore') @observer // 让组件响应store的变化,自动重新渲染 export default class StudentModal extends Component { renderStudentCount() { const { studentCount } = this.props.studentModalStore; // 完善文本逻辑,覆盖0、1、多个的情况 if (studentCount > 1) { return `${studentCount} students`; } else if (studentCount === 1) { return `${studentCount} student`; } return 'No students'; } render() { return ( <div className="student-modal"> {/* 模态框的其他内容 */} <div className="student-count"> {this.renderStudentCount()} </div> </div> ); } }
4. 在根组件用Provider提供Store
最后要确保在你的应用根组件(比如App.js)里用Provider把store传递给所有子组件:
import { Provider } from 'mobx-react'; import studentModalStore from './stores/StudentModalStore'; import StudentModal from './components/students/Modal'; function App() { return ( <Provider studentModalStore={studentModalStore}> {/* 你的应用其他组件 */} <StudentModal /> </Provider> ); } export default App;
关键点总结
- @computed:用于在Store里定义衍生值,只有当依赖的observable数据变化时才会重新计算,性能更优。
- @inject + Provider:实现store的全局共享,避免在组件里重复实例化store。
- @observer:让组件成为响应式组件,当store里的observable变化时自动重新渲染。
如果你的studentCount本身就是Store里的一个observable变量(比如直接存储数字),那只需要去掉Store里的@computed,直接用@observable studentCount = 0即可,组件里的用法不变。
内容的提问来源于stack exchange,提问作者Joseph Chambers
相关产品推荐
相关产品推荐

