Closed nickfla1 closed 4 years ago
Hi @nickfla1 ,
Before we get the devs involved, would you be able to create a reproducible example?
I'm having the same problem, any solutions?
@ItsNoHax
I will provide a demo project as soon as possible
I'm having a similar issue for both Android and iOS. componentDidAppear
is not being called after calling dismissModal()
. Example: there's a modal currently showing, I launch another modal on top of that using showModal()
, when I dismiss this modal the original one does not trigger the componentDidAppear()
method. Not sure if is the expected behaviour in V3, but in V2 componentDidAppear()
would be invoked. I'm also using 3.2.0 with react-native 0.61.1
I faced with this problem too. Closing of any modal screen doesn't fire componentDidAppear
of underlying screen. RNN 0.60.5, RN 3.2.0
As a workaround, I tried subscribing to the componentDidDisappear
event as shown in the documentation and added a callback to update the view, and it seems to work.
componentDidAppear() {
this.myNavListener = Navigation.events().registerComponentDidDisappearListener(({ componentId, componentName }) => {
// stuff I do goes here
});
}
componentDidDisappear(){
this.myNavListener.remove()
}
However, is not really an optimal solution.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you believe the issue is still relevant, please test on the latest Detox and report back. Thank you for your contributions.
The issue has been closed for inactivity.
Can you reopen please? I am also experiencing this. We have tried to use multiple events instead of componentDidAppear
, such as setRoot
or push
but none of them are as consistent as componentDidAppear
was.
I went ahead and reopened this issue for you @idanlo . If you guys could provide a reproducible example, I can push this forward to the devs so they can plan it in their sprint.
@yogevbd Any chance this is related to animation completion blocks sometimes running on background thread?
I have this problem too. Firstly, I set a stackRoot with 4 tabs. 2nd, I push to a screen then I setRoot again with 4 tabs again. But when I tab on the second tab, ComponentDidAppear's not working. Log and have 3 times didmount and 2 times unmount as expected. All socket listener I have in ComponentDidMount not work also (Did unsubscribed these socket event on componentWillUnmount)
componentDidMount(){
this.navigationEventListener = Navigation.events().bindComponent(this);
console.log('loggedIn',this.props.loggedIn)
console.log('sockettesting',this.props.socket)
if (this.props.loggedIn && this.props.socket) {
this.props.socket.on('reloadInbox', (data) => {
console.log('Reload Inbox:', data);
this.getDataWithSocket()
});
this.props.socket.on('createdBooking', (data) => {
console.log('createdBooking', data);
this.getDataWithSocket()
})
this.props.socket.on('TouristCancelledBooking',data => {
console.log('cancelbookingdata',data);
this.getDataWithSocket()
})
this.getConversations()
}
}
shouldComponentUpdate(nextProps, nextState){
return !_.isEqual(this.state.data, nextState.data)
}
componentWillUnmount() {
console.log('unmounted')
if (this.props.loggedIn && this.props.socket) {
this.props.socket.off('reloadInbox')
this.props.socket.off('createdBooking')
this.props.socket.off('TouristCancelledBooking')
}
if (this.navigationEventListener) {
this.navigationEventListener.remove();
}
}
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you believe the issue is still relevant, please test on the latest version and report back. Thank you for your contributions.
I'm also having this issue where the root component in a stack or by itself invokes the componentDidAppear function; however, subsequent screens are not called. I tested whether or not the listener is actually listening to the other screen's appearance - it did.
I'll test this issue on a demo project and I will come back with results about this matter.
I came back with my results. I made a basic demo project using the example in the documentation.
The result is it works. Upon inspection of my own project, I noticed that using HOC components will not trigger subsequent components for the first time.
After few hours, I figured out that the problem lies in my HOC component.
Example of my screen registration:
Navigation.registerComponent("component", () => HOC(Component), () => Component);
The HOC component checks whether or not the user is authenticated. Since authentication is an async process, I render a blank screen instead of the actual wrapped screen so componentDidAppear does get executed for the blank screen (null) but rendering to the screen after authentication will not trigger componentDidAppear (the component with the defined componentDidAppear) since the overall HOC component has appeared to the user long before the actual screen is shown.
Solution:
const Provider = (Component) => (props) => {
const [ user, initializing ] = CustomHook();
return <Component initializing={initializing} user={user} {...props} />;
}
I handle the initial componentDidAppear using componentDidUpdate and a stateful boolean property in my Component
.
export default ExampleComponent extends Component {
constructor(props) {
this.state = { init: false };
}
componentDidUpdate() {
const { init } = this.state;
const { initializing } = this.props;
if (!init && !initializing) {
// Do initial componentDidAppear
this.setState({ init: true });
}
}
}
All good
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you believe the issue is still relevant, please test on the latest version and report back. Thank you for your contributions.
The issue has been closed for inactivity.
I had the same problem. After playing with the sample app, which works as expected,
I dug a little deeper. And as it turned out, I was missing a line.
class ExampleScreen extends NavigationComponent<Props> {
constructor(props: Props) {
super(props);
Navigation.events().bindComponent(this); // <=== HERE
}
}
Maybe this should be mention in the docs?
I had the same problem. After playing with the sample app, which works as expected,
I dug a little deeper. And as it turned out, I was missing a line.
class ExampleScreen extends NavigationComponent<Props> { constructor(props: Props) { super(props); Navigation.events().bindComponent(this); // <=== HERE } }
Maybe this should be mention in the docs?
Same issue in ios app, how could I do it in function component?
I mention when u provide your component with Navigation.registerComponent("component", () => HOC(Component), () => Component);
my bottoms Tabs DESKTOP - ConferencesList - NotificationList - MENU my Logs
LOG componentDidDisappear DESKTOP
LOG componentDidAppear ConferencesList
LOG did appear ConferencesList DESKTOP
LOG did appear ConferencesList ConferencesList
LOG did appear ConferencesList
LOG componentDidDisappear ConferencesList
LOG did appear NotificationList DESKTOP
LOG did appear NotificationList ConferencesList
LOG componentDidDisappear NotificationList
LOG did appear MENU DESKTOP
LOG did appear MENU ConferencesList
LOG did appear MENU NotificationList
my hook
export const useMainBottomTabScreen = () => {
const {componentId} = useContext(NavigationContext);
const {setMainBottomTabCurrentComponentId} = useNavigationStateStore();
useMemo(() => {
const componentAppearListener =
Navigation.events().registerComponentDidAppearListener(
({componentId: compId}) => {
console.log('did appear', compId, componentId);
if (compId === componentId) {
console.log('did appear', compId);
}
},
);
const unsubscribe = Navigation.events().registerComponentListener(
{
componentDidAppear: () => {
console.log('componentDidAppear', componentId);
if (componentId) {
setMainBottomTabCurrentComponentId(componentId);
}
},
componentWillAppear: () => {
console.log(' componentWillAppear', componentId);
if (componentId) {
setMainBottomTabCurrentComponentId(componentId);
}
},
navigationButtonPressed: () => {
console.log('navigationButtonPressed', componentId);
},
componentDidDisappear: () => {
console.log('componentDidDisappear', componentId);
},
},
componentId ?? '',
);
return () => {
unsubscribe.remove();
componentAppearListener.remove();
};
}, [componentId, setMainBottomTabCurrentComponentId]);
};
as u can see if i go fast from 1 to 2 to 3 to 4 componentDidAppear does not trigger
@9r4ik have you tried registering the events directly?
export const useMainBottomTabScreen = () => {
const { componentId } = useContext(NavigationContext);
const { setMainBottomTabCurrentComponentId } = useNavigationStateStore();
useMemo(() => {
const componentAppearListener =
Navigation.events().registerComponentDidAppearListener(
({ componentId: compId }) => {
console.log('did appear', compId, componentId);
if (compId === componentId) {
console.log('did appear', compId);
}
},
);
const listeners = [
Navigation.events().registerComponentDidAppearListener((event) => {
console.log('componentDidAppear', event.componentId);
if (event.componentId) {
setMainBottomTabCurrentComponentId(event.componentId);
}
}),
Navigation.events().registerComponentWillAppearListener((event) => {
console.log(' componentWillAppear', event.componentId);
if (event.componentId) {
setMainBottomTabCurrentComponentId(event.componentId);
}
}),
Navigation.events().registerNavigationButtonPressedListener((event) => {
console.log('navigationButtonPressed', event.componentId);
}),
Navigation.events().registerComponentDidDisappearListener((event) => {
console.log('componentDidDisappear', event.componentId);
}),
];
return () => {
listeners.forEach((listener) => listener.remove());
componentAppearListener.remove();
};
}, [componentId, setMainBottomTabCurrentComponentId]);
};
is there any difference in behaviour?
PS: I didn't test the sample, because i'm not familiar with functional components. Nevertheless, it should work just fine.
Issue Description
Sometimes pushing a component to the stack does not invoke its
componentDidAppear
method. Debugging I've noticed that the component is correctly added to thelisteners
map inComponentEventsObserver.js
but the methodnotifyComponentDidAppear
is never called. I've also tried to debug the native code, as this method is invoked by a native event, but I was unable to reproduce this issue while debugging. Maybe the native code runs faster than the JavaScript application, firing the event before the component is even added to the mapping?EDIT: This issue shows up only on the devices listed below below. We've also tested it on an Honor 10, a Samsung S10 and a Samsung Galaxy J3 2016 but the application runs without problems on these devices.
Environment