尝试使用 useState 钩子(Hook)更新对象状态在 RxJS 主题订阅体内部不起作用,但在其外部起作用。 (用第二段代码中的注释进行注释)
我收到的错误是:TypeError: eventMap.addEvent is not a function
我的目标是使用 backpageMessageSubject$ 中的事件从 EventMap 调用 addEvent,然后将 getNthEvent 方法返回的数组传递给子组件。
class EventMap {
eventArrays;
constructor() {
this.eventArrays = new Map();
}
addEvent = (id, data) => {
this.eventArrays.has(id)
? this.eventArrays.get(id).push(data)
: this.eventArrays.set(id, [data]);
return this.eventArrays;
}
getNthEvent = (n) => {
const result = [];
for (let key of this.eventArrays.keys()) {
result.push(this.eventArrays.get(key)[n]);
}
return result;
}
}
export default function MarbleDiagram(props) {
const [eventMap, setEventMap] = useState(new EventMap());
// Stream of events for this observable.
const event$ = backpageMessageSubject$.pipe(
filter(message => message.type === 'event'),
map(message => message.event),
filter(event => event.observable === props.observable)
);
useEffect(() => {
const eventSubscription = event$.subscribe(event => {
setEventMap(eventMap => eventMap.addEvent(1, 1)); // This does trigger error.
});
setEventMap(eventMap => eventMap.addEvent(1, 1)); // This does not trigger error.
return () => {
eventSubscription.unsubscribe();
};
}, []);
}
主题来源:
export const backpageMessageSubject$ = new Subject();
最佳答案
完成 setEventMap(eventMap => eventMap.addEvent(1, 1))
后,事件映射的状态就是返回值 eventMap.addEvent
的,它不是 EventMap
实例。因此,稍后当您尝试使用它时,它会失败,因为您正在使用的内容(Map
)没有addEvent
。
由于状态中的项目不得直接修改,因此您需要更新 EventMap
以便它返回具有添加事件的 map 的新实例,而不是改变现有 map ,以及这些行:
class EventMap {
eventArrays;
constructor(eventArrays = new Map()) { // Note accepting a parameter
this.eventArrays = eventArrays;
}
addEvent = (id, data) => {
// Copy the current map, reusing the same arrays
const eventArrays = new Map(this.eventArrays);
// Get the current array for this `id`
const current = eventArrays.get(id);
if (!current) {
// We don't have it, create a new one in the new map
eventArrays.set(id, [data]);
} else {
// We have it, copy its contents to a new array and
// add the new data to the end, storing it in the
// new map
eventArrays.set(id, [...current, data]);
}
// Create a new EventMap with those arrays and return it
return new EventMap(eventArrays);
}
getNthEvent = (n) => {
const result = [];
for (let key of this.eventArrays.keys()) {
result.push(this.eventArrays.get(key)[n]);
}
return result;
}
}
关于javascript - 无法在订阅主体内的 setState Hook 中调用先前状态的对象方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60529036/