From f48282752af045c1d3c1eed82230076f038b00d4 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Wed, 27 May 2020 21:52:34 -0700 Subject: [PATCH] [FOR DISCUSSION] One way to get `sharedData` into ShareToStream, ShareToPm This is just meant to show one way this could be done -- it seems more React- and React-Navigation idiomatic. It avoids calling `createMaterialTopTabNavigator` from within a render method or a constructor. This uses the alternative mentioned at the "Common Mistakes" doc [1], with the `router` static and threading through the `navigation` prop. There are a few comments I would make about some of the code, not addressed in this commit, but hopefully this will help for conceptual clarity about the kind of thing I'm suggesting. :) More discussion at https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/.60screenProps.60.20in.20react-navigation.20v2/near/888521. [1]: https://reactnavigation.org/docs/2.x/common-mistakes/#explicitly-rendering-more-than-one-navigator --- src/sharing/SharingScreen.js | 106 +++++++++++++++++------------------ 1 file changed, 51 insertions(+), 55 deletions(-) diff --git a/src/sharing/SharingScreen.js b/src/sharing/SharingScreen.js index cad4d9d0469..b74c233d325 100644 --- a/src/sharing/SharingScreen.js +++ b/src/sharing/SharingScreen.js @@ -1,7 +1,7 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { View, StyleSheet, Image, ScrollView, Modal, BackHandler } from 'react-native'; -import type { NavigationScreenProp } from 'react-navigation'; +import type { NavigationScreenProp, NavigationNavigatorProps } from 'react-navigation'; import { createMaterialTopTabNavigator } from 'react-navigation'; import { BRAND_COLOR } from '../styles/constants'; import type { Dispatch, SharedData, Subscription, User, Auth } from '../types'; @@ -68,6 +68,8 @@ type ShareToStreamProps = $ReadOnly<{| dispatch: Dispatch, subscriptions: Map, auth: Auth, + + ...$Exact>, |}>; type ShareToStreamState = $ReadOnly<{| @@ -82,7 +84,7 @@ class ShareToStreamComponent extends React.Component { const { stream, topic, message } = this.state; - const { sharedData } = this.props; + const { sharedData } = this.props.navigation.state.params; if (sharedData.type !== 'text') { return stream !== '' && topic !== ''; @@ -150,7 +152,8 @@ class ShareToStreamComponent extends React.Component { const { topic, stream, message } = this.state; let messageToSend = message; - const { auth, sharedData } = this.props; + const { auth } = this.props; + const { sharedData } = this.props.navigation.state.params; try { showToast('Sending Message...'); @@ -176,7 +179,7 @@ class ShareToStreamComponent extends React.Component>, |}>; type ShareToPmState = $ReadOnly<{| @@ -258,7 +263,7 @@ type ShareToPmState = $ReadOnly<{| class ShareToPmComponent extends React.Component { constructor(props) { super(props); - const { sharedData } = props; + const { sharedData } = this.props.navigation.state.params; this.state = { users: [], message: sharedData.type === 'text' ? sharedData.sharedText : '', @@ -288,7 +293,7 @@ class ShareToPmComponent extends React.Component isSendButtonEnabled = () => { const { message, users } = this.state; - const { sharedData } = this.props; + const { sharedData } = this.props.navigation.state.params; if (sharedData.type === 'text') { return message !== '' && users.length > 0; @@ -320,7 +325,8 @@ class ShareToPmComponent extends React.Component handleSend = async () => { const { users, message } = this.state; let messageToSend = message; - const { auth, sharedData } = this.props; + const { auth } = this.props; + const { sharedData } = this.props.navigation.state.params; const to = JSON.stringify(users.map(user => user.user_id)); try { @@ -346,6 +352,7 @@ class ShareToPmComponent extends React.Component render() { const { message, choosingRecipients } = this.state; + const { sharedData } = this.props.navigation.state.params; if (choosingRecipients) { return ( @@ -355,7 +362,6 @@ class ShareToPmComponent extends React.Component ); } - const { sharedData } = this.props; let sharePreview = null; if (sharedData.type === 'image') { sharePreview = ( @@ -413,58 +419,48 @@ type Props = $ReadOnly<{| dispatch: Dispatch, |}>; -class SharingScreen extends PureComponent { - SharingTopTabNavigator; - - constructor(props) { - super(props); - const { navigation } = this.props; - const sharedData: SharedData = navigation.state.params.sharedData; - - this.SharingTopTabNavigator = createMaterialTopTabNavigator( - { - Stream: { - screen: () => , - }, - 'Private Message': { - screen: () => , - }, +const SharingTopTabNavigator = createMaterialTopTabNavigator( + { + // $FlowFixMe + Stream: ShareToStream, + // $FlowFixMe + 'Private Message': ShareToPm, + }, + { + tabBarPosition: 'top', + animationEnabled: true, + tabBarOptions: { + upperCaseLabel: false, + pressColor: BRAND_COLOR, + activeTintColor: BRAND_COLOR, + inactiveTintColor: 'gray', + labelStyle: { + fontSize: 14, + margin: 0, + padding: 10, }, - { - tabBarPosition: 'top', - animationEnabled: true, - tabBarOptions: { - upperCaseLabel: false, - pressColor: BRAND_COLOR, - activeTintColor: BRAND_COLOR, - inactiveTintColor: 'gray', - labelStyle: { - fontSize: 14, - margin: 0, - padding: 10, - }, - indicatorStyle: { - backgroundColor: BRAND_COLOR, - }, - tabStyle: { - flex: 1, - }, - style: { - backgroundColor: 'transparent', - borderWidth: 0, - elevation: 0, - }, - }, + indicatorStyle: { + backgroundColor: BRAND_COLOR, }, - ); - } + tabStyle: { + flex: 1, + }, + style: { + backgroundColor: 'transparent', + borderWidth: 0, + elevation: 0, + }, + }, + }, +); - render() { - const { SharingTopTabNavigator } = this; +class SharingScreen extends PureComponent { + static router = SharingTopTabNavigator.router; + render() { return ( - + ); }