Skip to content

Commit

Permalink
Changes StackNavigator.Screen from stateless to statelessWithRetained…
Browse files Browse the repository at this point in the history
…Props

It allow us to check for header props changes and call navigation.setOptions when props changes. Should fix callstackincubator#122. Only problem are properties that are recreated every time like Style.t or (probably) Header.returnsComponent.
  • Loading branch information
baransu committed Sep 6, 2018
1 parent 60dea4c commit c5f4449
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 11 deletions.
31 changes: 25 additions & 6 deletions example/Admin.re
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
open Rebolt;

let component = ReasonReact.statelessComponent("Admin");
type action =
| Increment;

type state = {counter: int};

let component = ReasonReact.reducerComponent("Admin");

module Styles = {
open Style;
Expand All @@ -15,13 +20,15 @@ module Styles = {
marginTop(Pt(16.)),
backgroundColor(String(color)),
borderRadius(20.),
width(Pt(100.)),
width(Pt(120.)),
]);
let buttonText = style([textAlign(Center)]);
let title = style([fontSize(Float(20.))]);
};

let renderButtons = (nav: NavigationConfig.StackNavigator.navigation) =>
let getHeaderTitle = counter => "Admin" ++ string_of_int(counter);

let renderButtons = (nav: NavigationConfig.StackNavigator.navigation, send) =>
<View>
<TouchableOpacity
style=(Styles.button("#4cd964"))
Expand All @@ -32,13 +39,25 @@ let renderButtons = (nav: NavigationConfig.StackNavigator.navigation) =>
style=(Styles.button("#ff9500")) onPress=(_e => nav.pop())>
<Text style=Styles.buttonText> (ReasonReact.string("Pop")) </Text>
</TouchableOpacity>
<TouchableOpacity
style=(Styles.button("rgb(63,97,165)"))
onPress=(_e => send(Increment))>
<Text style=Styles.buttonText>
(ReasonReact.string("Change header title"))
</Text>
</TouchableOpacity>
</View>;

let make = (~navigation, _children) => {
...component,
render: _self =>
initialState: () => {counter: 0},
reducer: (action, state) =>
switch (action) {
| Increment => ReasonReact.Update({counter: state.counter + 1})
},
render: self =>
<NavigationConfig.StackNavigator.Screen
headerTitle="Admindkasldkasldkdasdas"
headerTitle=(getHeaderTitle(self.state.counter))
navigation
headerStyle=Style.(style([backgroundColor(String("#FFF"))]))>
...(
Expand All @@ -47,7 +66,7 @@ let make = (~navigation, _children) => {
<Text style=Styles.title>
(ReasonReact.string("Admin screen"))
</Text>
(renderButtons(navigation))
(renderButtons(navigation, self.send))
</View>
)
</NavigationConfig.StackNavigator.Screen>,
Expand Down
52 changes: 49 additions & 3 deletions src/StackNavigator.re
Original file line number Diff line number Diff line change
Expand Up @@ -541,8 +541,19 @@ module CreateStackNavigator = (Config: {type route;}) => {
},
};
module Screen = {
type retainedProps = {
style: option(Style.t),
headerTitle: option(string),
/* headerStyle: option(Style.t), */
headerLeft: option(Header.returnsComponent),
headerCenter: option(Header.returnsComponent),
headerRight: option(Header.returnsComponent),
animation: option(Animation.t),
};

let flexOne = Style.(style([flex(1.)]));
let component = ReasonReact.statelessComponent("CallstackScreen");
let component =
ReasonReact.statelessComponentWithRetainedProps("CallstackScreen");
let make =
(
~navigation: navigation,
Expand All @@ -556,7 +567,16 @@ module CreateStackNavigator = (Config: {type route;}) => {
children,
) => {
...component,
didMount: _self => {
retainedProps: {
style,
headerTitle,
/* headerStyle, */
headerLeft,
headerCenter,
headerRight,
animation,
},
didMount: _self =>
navigation.setOptions({
header: {
title: headerTitle,
Expand All @@ -567,7 +587,33 @@ module CreateStackNavigator = (Config: {type route;}) => {
},
animation,
style,
});
}),
didUpdate: ({oldSelf: {retainedProps}}) => {
let propsChanged =
[
retainedProps.style !== style,
retainedProps.headerTitle !== headerTitle,
/* oldSelf.retainedProps.headerStyle !== headerStyle, */
retainedProps.headerLeft !== headerLeft,
retainedProps.headerCenter !== headerCenter,
retainedProps.headerRight !== headerRight,
retainedProps.animation !== animation,
]
|> Belt.List.some(_, a => a);

if (propsChanged) {
navigation.setOptions({
header: {
title: headerTitle,
style: headerStyle,
center: headerCenter,
left: headerLeft,
right: headerRight,
},
animation,
style,
});
};
();
},
render: _self => {
Expand Down
13 changes: 11 additions & 2 deletions src/StackNavigator.rei
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ module CreateStackNavigator:
);
module Animation = Animation;
module Screen: {
type retainedProps = {
style: option(Rebolt.Style.t),
headerTitle: option(string),
/* headerStyle: option(Rebolt.Style.t), */
headerLeft: option(Header.returnsComponent),
headerCenter: option(Header.returnsComponent),
headerRight: option(Header.returnsComponent),
animation: option(Animation.t),
};
let make:
(
~navigation: navigation,
Expand All @@ -55,8 +64,8 @@ module CreateStackNavigator:
ReasonReact.componentSpec(
ReasonReact.stateless,
ReasonReact.stateless,
ReasonReact.noRetainedProps,
ReasonReact.noRetainedProps,
retainedProps,
retainedProps,
ReasonReact.actionless,
);
};
Expand Down

0 comments on commit c5f4449

Please sign in to comment.