我正在使用socket.io
,我有一个使用属性作为ID键的组件,如this.props.dataKey
,以确定要订阅的Web套接字路径。
var path = "/data/" + this.props.dataKey + "/subdata"
socket.on(path, handleData.bind(this));
我注意到的一件事是,在卸载组件时会调用handleData
函数,因此我在componentWillUnmount
但是,如果数据键属性发生更改,我也想处理它并取消订阅旧路径并订阅新路径。
我首先使用componentWillUpdate
和componentWillMount
来跟踪订阅/取消订阅,但我注意到这些日期在16.3中被标记为已弃用
所以我开始使用getDerivedStateFromProps写入状态,如果属性state = {path,lastpath, subscribed}
,然后在渲染方法中订阅!订阅取消订阅到最后一个路径并订阅新路径
if(!this.state.subscribed)
{
if(this.state.lastpath){socket.removeListener(this.state.lastpath);}
socket.on(this.state.path, handleData.bind(this));
this.setState({subscribed:true});
}
不幸的是我得到一个警告,说在渲染中设置状态是一个anit-pattern,我应该使用componentWillMount。但是componentWillMount仅在创建时触发,而不是在更新时触发,这意味着更改的道具效果不会受到影响。另外,不推荐使用componentWillMoutn和componentWillUpdate。那么处理这个问题的适当场所是什么?它无法在getDerrivedStateFromProps中处理,这是一个静态函数。
答案 0 :(得分:1)
我认为你走在正确的轨道上
class Component extends React.Component {
static propTypes = {
dataKey: PropTypes.string.isRequired
}
state = {
dataKey: false
}
getDerivedStateFromProps(nextProps, prevState) {
return {
dataKey: nextProps.dataKey
}
}
componentDidUpdate(prevProps, prevState) {
if (this.state.dataKey !== prevState.dataKey) {
this.subscribe(this.state.dataKey)
}
if(prevState.dataKey && this.state.dataKey &&
prevState.dataKey !== this.state.dataKey) {
this.unsubscribe(prevState.dataKey)
}
}
componentWillUnmount() {
this.unsubscribe(this.state.dataKey)
}
subscribe(key) {
const path = `/data/${key}/subdata`
socket.on(path, this.handleData.bind(this));
}
handleData(data) {
console.log(data)
}
unsubscribe(key) {
socket.unsubscribe(key)
}
}
Dan Abramov的地图可以提供帮助