ComponentwillMount 被调用两次
Posted
技术标签:
【中文标题】ComponentwillMount 被调用两次【英文标题】:ComponentwillMount is called twice 【发布时间】:2016-12-13 09:01:44 【问题描述】:I'm my componentWillMount()
每次切换路线时都会被调用。
还有其他方法可以处理商店状态的变化吗?
当我第一次使用这两个功能时没问题,但是当我切换路线并返回并尝试再次使用它们时,我收到此消息
warning.js:45 Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the undefined component.
InventoryList.js
import React from "react";
import InventoryItem from "../components/InventoryItem";
import InventoryItemStore from "../stores/InventoryItemStore";
import Link from "react-router";
export default class InventoryList extends React.Component
constructor()
super();
this.state =
items: InventoryItemStore.getAll(),
componentWillMount()
InventoryItemStore.on("change", () =>
this.setState(
items: InventoryItemStore.getAll()
);
);
render(...);
InventoryStore.js
import EventEmitter from "events";
import dispatcher from "../dispatcher";
class InventoryItemStore extends EventEmitter
constructor()
super()
this.items = [
id: 1,
title: "first item",
stockQuantity: 10
,
id: 2,
title: "second item",
stockQuantity: 5
];
getAll()
return this.items;
// Adds new item to the inventory store
addItem( title, stockQuantity )
const id = Date.now();
this.items.push(
id,
title, // We don't have to do title: title because of ES6... Thx ES6
stockQuantity
);
this.emit("change");
/**
* Lower the stock quantity of certain item
* @param integer id
* @param integer stockQuantity
*/
lowerQuantity( id, orderQuantity )
this.items.map((item) =>
if ( item.id == id )
item.stockQuantity = item.stockQuantity - orderQuantity;
);
this.emit("change");
handleActions( action )
switch( action.type )
case "ADD_ITEM":
const title, stockQuantity = action;
this.addItem( title, stockQuantity );
case "LOWER_QUANTITY":
const id, orderQuantity = action;
this.lowerQuantity( id, orderQuantity );
const inventoryItemStore = new InventoryItemStore;
dispatcher.register(inventoryItemStore.handleActions.bind(inventoryItemStore));
export default inventoryItemStore;
【问题讨论】:
您是否会尝试编写一些代码来从 componentWillUnmount 的 InventoryItemStore 中解除“更改”事件的绑定?更改 react-router 时,您的组件将卸载然后重新安装。如果您不从存储中取消绑定“更改”事件,最后会保留两个事件。它会导致事件监听器被调用两次。 感谢您的评论,您是对的,但我不知道要在componentWillUnmount
中添加什么代码才能真正删除更改事件侦听器
【参考方案1】:
您的组件会在您每次更改路由时卸载,并且在您更改回路由时会安装一个新组件。
由于您使用 InventoryItemStore.on
注册了一个事件处理程序,但从未取消注册它,因此您会留下两个正在监听 change
的组件,而一个未安装的组件会引发错误。
使用componentWillUnmount
取消注册您的组件,这样它就不会像幽灵一样徘徊并在您导航返回时困扰您。
有关更多生命周期挂钩,请参阅 React lifecycle。
【讨论】:
哦,非常感谢,我不知道componentWillUnmount
的确切用途是什么,但现在我明白了:)
但是你认为你可以指出,我应该把componentWillUnmount
放在哪里?
在 InventoryList.js
对不起,我问错了。如何实际卸载事件。我放置了componentWillUnmount
,但我不知道如何取消绑定“更改”事件监听器
@JakubKohout 你使用removeListener
,它在this答案中得到了展示。以上是关于ComponentwillMount 被调用两次的主要内容,如果未能解决你的问题,请参考以下文章
react请求接口数据是在componentDidMount 还是componentWillMount周期好
为啥在调用 c++ fork 函数之前创建的值没有被父进程和子进程修改两次?