React使用Mock.js调用unsubscribe报错:_mock.default.unsubscribe is not a function
Hey Zak, let's break down this unsubscribe issue you're hitting with Mock.js and your tbodyCommand.reducer.js store reducer. I've dealt with similar mix-ups between Mock tools and RxJS before, so here's what's going on and how to fix it:
unsubscribe is not a function Error The core problem here is straightforward: Mock.js itself is not a RxJS Observable. The .unsubscribe() method is exclusive to RxJS Subscription objects, so calling it directly on a Mock.js return value (which is usually a plain JavaScript object or synchronous data) will always throw that TypeError. The RxJS version fix you found earlier applies to actual Observable streams, not Mock.js's mock data.
Let's cover the most common cases you might be in, with actionable fixes:
1. Wrap Mock Data in a RxJS Observable (If You Need a Stream)
If you're trying to simulate an Observable data stream (like you would get from an API call), you need to wrap your Mock.js-generated data into a proper RxJS Observable first. This gives you a valid Subscription object to unsubscribe from:
import { of } from 'rxjs'; import Mock from 'mockjs'; // Generate 10 rows of mock data const mockDataset = Mock.mock({ 'rows|10': [{ 'id|+1': 1, 'content': '@sentence(5, 10)', 'status': '@pick(["active", "pending", "completed"])' }] }); // Wrap mock data into an Observable const mockStream = of(mockDataset.rows); // Subscribe and save the Subscription object const dataSubscription = mockStream.subscribe(rows => { // Update your store reducer with the data dispatch({ type: 'LOAD_TABLE_DATA', payload: rows }); }); // Later, when you need to unsubscribe: dataSubscription.unsubscribe(); // This will work now!
2. Use a Flag for Synchronous Mock Data (No Observable Needed)
If you're just fetching synchronous Mock data (no ongoing stream), the "unsubscribe" concept doesn't apply. Instead, use a boolean flag to control whether the data updates your store:
let shouldUpdateStore = true; // Get mock data directly const mockRows = Mock.mock({ 'rows|10': [...] }).rows; // Only update store if still "subscribed" if (shouldUpdateStore) { dispatch({ type: 'LOAD_TABLE_DATA', payload: mockRows }); } // When you want to "cancel" future updates: shouldUpdateStore = false;
3. If Using Mock.js with an HTTP Client (e.g., Axios/HttpClient)
If Mock.js is intercepting HTTP requests that would normally return an Observable (like Angular's HttpClient), make sure you're subscribing to the HTTP client's Observable, not the Mock.js response. Mock.js just replaces the real API data—it doesn't touch the Observable itself:
import { HttpClient } from '@angular/common/http'; // Mock.js intercepts this request and returns mock data const apiStream = httpClient.get('/api/table-data'); // Subscribe to the HTTP Observable (not Mock.js directly) const subscription = apiStream.subscribe(rows => { dispatch({ type: 'LOAD_TABLE_DATA', payload: rows }); }); // Unsubscribe normally subscription.unsubscribe();
If you're working in React/Vue, you can leverage lifecycle hooks to automatically clean up subscriptions without manual calls:
// React example with useEffect import { useEffect } from 'react'; import { of } from 'rxjs'; import Mock from 'mockjs'; function TableComponent() { useEffect(() => { const mockRows = Mock.mock({ 'rows|10': [...] }).rows; const subscription = of(mockRows).subscribe(rows => { dispatch({ type: 'LOAD_TABLE_DATA', payload: rows }); }); // Auto-unsubscribe when component unmounts return () => subscription.unsubscribe(); }, []); // ... rest of component }
内容的提问来源于stack exchange,提问作者Zak the Gear

