getting rid of UNSAFE_componentWillReceiveProps

This commit is contained in:
or-else
2019-02-24 19:30:11 +03:00
parent 5d17ef7039
commit 79970cf558
5 changed files with 275 additions and 246 deletions
+125 -125
View File
@@ -46,23 +46,9 @@ class MessagesView extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
console.log(props.acs); this.state = MessagesView.getDerivedStateFromProps(props, {});
this.state = { // this.propsChange = this.propsChange.bind(this);
messages: [],
onlineSubs: [],
topic: '',
title: '',
avatar: null,
scrollPosition: 0,
readOnly: props.acs ? !props.acs.isWriter() : true,
writeOnly: props.acs ? !props.acs.isReader() : true,
unconfirmed: isUnconfirmed(props.acs),
typingIndicator: false,
imagePreview: null
};
this.propsChange = this.propsChange.bind(this);
this.leave = this.leave.bind(this); this.leave = this.leave.bind(this);
this.handleScrollReference = this.handleScrollReference.bind(this); this.handleScrollReference = this.handleScrollReference.bind(this);
this.handleScrollEvent = this.handleScrollEvent.bind(this); this.handleScrollEvent = this.handleScrollEvent.bind(this);
@@ -81,7 +67,7 @@ class MessagesView extends React.Component {
} }
componentDidMount() { componentDidMount() {
this.propsChange(this.props, this.state); // this.propsChange(this.props, this.state);
if (this.messagesScroller) { if (this.messagesScroller) {
this.messagesScroller.addEventListener('scroll', this.handleScrollEvent); this.messagesScroller.addEventListener('scroll', this.handleScrollEvent);
} }
@@ -98,100 +84,32 @@ class MessagesView extends React.Component {
// or vertical shrinking. // or vertical shrinking.
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
if (this.messagesScroller) { if (this.messagesScroller) {
if (prevState.title != this.state.title || prevState.messages.length != this.state.messages.length) { if (prevState.topic != this.state.topic || prevState.messages.length != this.state.messages.length) {
this.messagesScroller.scrollTop = this.messagesScroller.scrollHeight - this.state.scrollPosition; this.messagesScroller.scrollTop = this.messagesScroller.scrollHeight - this.state.scrollPosition;
} else if (prevProps.viewportHeight > this.props.viewportHeight) { } else if (prevProps.viewportHeight > this.props.viewportHeight) {
this.messagesScroller.scrollTop += prevProps.viewportHeight - this.props.viewportHeight; this.messagesScroller.scrollTop += prevProps.viewportHeight - this.props.viewportHeight;
} }
} }
}
//static getDerivedStateFromProps(nextProps, prevState) { const topic = this.props.tinode.getTopic(this.state.topic);
// if (this.state.topic != prevState.topic) {
//} if (prevState.topic) {
this.leave(prevState.topic);
this.props.readTimerHandler(null);
}
// Deprecated! if (topic) {
UNSAFE_componentWillReceiveProps(nextProps) { topic.onData = this.handleNewMessage;
this.propsChange(nextProps, this.state); topic.onAllMessagesReceived = this.handleAllMessagesReceived;
} topic.onInfo = this.handleInfoReceipt;
topic.onMetaDesc = this.handleDescChange;
propsChange(nextProps, prevState) { topic.onSubsUpdated = this.handleSubsUpdated;
const nextState = {}; topic.onPres = this.handleSubsUpdated;
if (!nextProps || !nextProps.topic) { }
const oldTopic = prevState.topic;
this.setState({messages: [], onlineSubs: [], topic: null}, this.leave(oldTopic));
return;
} }
if (!nextProps.connected) { if (topic && !topic.isSubscribed() &&
// connection lost, clear online subs ((!prevProps.connected && this.props.connected) || (this.state.topic != prevState.topic))) {
this.setState({onlineSubs: []});
return;
}
const topic = nextProps.tinode.getTopic(nextProps.topic);
if (!topic) {
return;
}
let newGroupTopic = Tinode.isNewGroupTopicName(nextProps.topic);
let tryToResubscribe = !nextProps.connected && nextProps.connected;
if (nextProps.topic != prevState.topic) {
const msgs = [];
const subs = [];
// Bind the new topic to component.
// FIXME: getDerivedStateFromProps is static, "this" is unaccessible.
// Move to componentDidUpdate
topic.onData = this.handleNewMessage;
topic.onAllMessagesReceived = this.handleAllMessagesReceived;
topic.onInfo = this.handleInfoReceipt;
topic.onMetaDesc = this.handleDescChange;
topic.onSubsUpdated = this.handleSubsUpdated;
topic.onPres = this.handleSubsUpdated;
// Unbind the previous topic from this component.
// FIXME: getDerivedStateFromProps is static, "this" is unaccessible.
// Move to componentDidUpdate
this.leave(prevState.topic);
// FIXME: getDerivedStateFromProps is static, "this" is unaccessible.
this.handleDescChange(topic);
topic.subscribers((sub) => {
if (sub.online && sub.user != nextProps.myUserId) {
subs.push(sub);
}
});
topic.messages(function(msg) {
if (!msg.deleted) {
msgs.push(msg);
}
});
this.setState({
messages: msgs,
onlineSubs: subs,
topic: nextProps.topic,
imagePreview: null,
scrollPosition: 0
});
tryToResubscribe = true;
// The user switched to the new topic before the timer for
// the previous topic has triggered, kill it.
nextProps.readTimerHandler(null);
}
this.setState({
readOnly: nextProps.acs ? !nextProps.acs.isWriter() : true,
writeOnly: nextProps.acs ? !nextProps.acs.isReader() : true,
unconfirmed: isUnconfirmed(nextProps.acs)
});
console.log("propsChange", nextProps.acs, isUnconfirmed(nextProps.acs));
if (!topic.isSubscribed() && tryToResubscribe) {
// Don't request the tags. They are useless unless the user // Don't request the tags. They are useless unless the user
// is the owner and is editing the topic. // is the owner and is editing the topic.
const getQuery = topic.startMetaQuery() const getQuery = topic.startMetaQuery()
@@ -199,13 +117,16 @@ class MessagesView extends React.Component {
.withLaterSub() .withLaterSub()
.withLaterData(MESSAGES_PAGE) .withLaterData(MESSAGES_PAGE)
.withLaterDel(); .withLaterDel();
const setQuery = newGroupTopic ? nextProps.newGroupTopicParams : undefined; const setQuery = Tinode.isNewGroupTopicName(this.props.topic) ?
this.props.newGroupTopicParams : undefined;
// Show "loading" spinner. // Show "loading" spinner.
this.setState({ fetchingMessages: true }); this.setState({ fetchingMessages: true });
topic.subscribe(getQuery.build(), setQuery) topic.subscribe(getQuery.build(), setQuery)
.then((ctrl) => { .then((ctrl) => {
this.setState({topic: ctrl.topic}); if (this.state.topic != ctrl.topic) {
nextProps.onNewTopicCreated(nextProps.topic, ctrl.topic); this.setState({topic: ctrl.topic});
}
this.props.onNewTopicCreated(this.props.topic, ctrl.topic);
// If there are unsent messages, try sending them now. // If there are unsent messages, try sending them now.
topic.queuedMessages((pub) => { topic.queuedMessages((pub) => {
if (!pub._sending && topic.isSubscribed()) { if (!pub._sending && topic.isSubscribed()) {
@@ -214,29 +135,107 @@ class MessagesView extends React.Component {
}); });
}) })
.catch((err) => { .catch((err) => {
nextProps.onError(err.message, 'err'); console.log('Failed subscription to', this.state.topic);
const {formatMessage} = nextProps.intl; this.props.onError(err.message, 'err');
const blankState = MessagesView.getDerivedStateFromProps({}, {});
console.log("subscribe failed", nextProps.acs); blankState.title = this.props.intl.formatMessage(messages.not_found);
// FIXME: getDerivedStateFromProps is static, "this" is unaccessible this.setState(blankState);
// and returning newState is meaningless.
// Move to componentDidUpdate
this.setState({
title: formatMessage(messages.not_found),
avatar: null,
readOnly: true,
writeOnly: true,
unconfirmed: false,
fetchingMessages: false,
messages: [],
onlineSubs: [],
typingIndicator: false,
imagePreview: null
});
}); });
} }
} }
static getDerivedStateFromProps(nextProps, prevState) {
let nextState = {};
if (!nextProps.topic) {
// Default state: no topic.
nextState = {
messages: [],
onlineSubs: [],
topic: null,
title: '',
avatar: null,
imagePreview: null,
typingIndicator: false,
scrollPosition: 0,
fetchingMessages: false
};
} else if (nextProps.topic != prevState.topic) {
const topic = nextProps.tinode.getTopic(nextProps.topic);
nextState = {
topic: nextProps.topic,
imagePreview: null,
typingIndicator: false,
scrollPosition: 0,
fetchingMessages: false
};
if (topic) {
// Topic exists.
const msgs = [];
const subs = [];
if (nextProps.connected) {
topic.subscribers((sub) => {
if (sub.online && sub.user != nextProps.myUserId) {
subs.push(sub);
}
});
}
topic.messages(function(msg) {
if (!msg.deleted) {
msgs.push(msg);
}
});
nextState = Object.assign(nextState, {
messages: msgs,
onlineSubs: subs
});
if (topic.public) {
nextState = Object.assign(nextState, {
title: topic.public.fn,
avatar: makeImageUrl(topic.public.photo)
});
} else {
nextState = Object.assign(nextState, {
title: '',
avatar: null
});
}
} else {
// Invalid topic.
nextState = Object.assign(nextState, {
messages: [],
onlineSubs: [],
title: '',
avatar: null
});
}
}
let val = nextProps.acs ? !nextProps.acs.isWriter() : true;
if (val != prevState.readOnly) {
nextState.readOnly = val;
}
val = nextProps.acs ? !nextProps.acs.isReader() : true;
if (val != prevState.writeOnly) {
nextState.writeOnly = val;
}
val = isUnconfirmed(nextProps.acs);
if (val != prevState.unconformed) {
nextState.unconfirmed = val;
}
// Clear subscribers online when there is no connection.
if (!nextProps.connected && prevState.onlineSubs && prevState.onlineSubs.length > 0) {
nextState.onlineSubs = [];
}
return nextState;
}
leave(oldTopicName) { leave(oldTopicName) {
if (!oldTopicName) { if (!oldTopicName) {
return; return;
@@ -300,7 +299,6 @@ class MessagesView extends React.Component {
}); });
} }
console.log("handleDescChange", desc.acs);
if (desc.acs) { if (desc.acs) {
this.setState({ this.setState({
readOnly: !desc.acs.isWriter(), readOnly: !desc.acs.isWriter(),
@@ -311,6 +309,8 @@ class MessagesView extends React.Component {
} }
handleSubsUpdated() { handleSubsUpdated() {
console.log("handleSubsUpdated");
if (this.state.topic) { if (this.state.topic) {
var subs = []; var subs = [];
var topic = this.props.tinode.getTopic(this.state.topic); var topic = this.props.tinode.getTopic(this.state.topic);
+147 -118
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long