if I add anything inside componentWillUnmount nothing happening - javascript

I am trying to learn react myself.
I am trying to set session inside my componentWillUnmount.
but if I add anything inside componentWillUnmount nothing happening.
i debugged by adding console and debugger still nothing happening.
can you guys tell how to make my componentWillUnmount to work
so that in future I will fix it myself.
providing my relevant code snippet and sandbox below.
all my code is in RecipeReviewCard.js
https://codesandbox.io/s/1vqkz1own7
componentDidMount() {
console.log("componentDidMount---->");
}
componentWillUnmount() {
console.log("componentwillUnmount---->");
debugger;
window.sessionStorage.setItem(
"favoriteValues",
JSON.stringify(this.props.benchMarks)
);
}

As the name suggests, 'componentWillUnmount' will fire when the component is about to be taken out of the DOM (eg. when you switch tabs for example) and in your example the console.log indeed does fire. Use 'componentWillMount' to run the function when the component is loaded into the DOM

Related

Assigning onclick on button that is outside of current react app (php) gives unexpected behaviour

We are builidng react components for a php app, it doesn't really have much intergration but there's a php save button that is should listen for and save onclick. But there's a catch, for some reason most of functions i'm trying to use are just not getting ran. I'm working with react-form-hook and trying to run the onsubmit() with my function inside.
handleSubmit((data) => {
handleSaveOrderProducts(data, selectedProductsRef.current);
});
To assign this function to the button i have to listen for the button clicks with id, i tried different approaches but none seems to fix the problem. Ways to listen i tried:
Using https://www.npmjs.com/package/react-detect-click-outside#features lib
const productInformationContainerRef = useDetectClickOutside({
onTriggered(event) {
// #ts-ignore
if (event.target?.id === "save-order-button") {
console.log("save order button");
handleSubmit((data) => {
handleSaveOrderProducts(data, selectedProductsRef.current);
});
}
},
});
What i get in result? The callback itself runs, but the function (handlesubmit) is not. Even if i put a console.log in callback with data there's just nothing displayed.
Different approaches from this stackoverflow thread, mostly everything related to functional react Detect click outside React component .
If you had experience in something like this or have any theoretical knowledge please comment :)strong text

setOnNavigatorEvent callback not fired when switching tabs

I am working on an app powered by react-native#0.55.4 and react-native-navigation#1.1.474.
Initially, there is only a login screen (using Navigation.startSingleScreenApp). When the user logs in I call Navigation.startTabBasedApp (one of the tab components is my NavScreen). Whenever the user changes to another tab the root of the tab's stack is supposed to be displayed so I tried something like this:
class NavScreen extends React.PureComponent {
constructor(props) {
super(props)
this.props.navigator.setOnNavigatorEvent(this.toRootOnTabSelect.bind(this))
}
toRootOnTabSelect(event) {
const {id} = event
if (["bottomTabSelected", "bottomTabReselected"].includes(id)) {
this.props.navigator.popToRoot({
animated: true,
animationType: "fade",
})
}
}
render() {
return <Text>Whatever...</Text>
}
}
But for some reason my toRootOnTabSelect event handler method is not being called when I change tabs (by clicking on them - not by calling the switchToTab API method).
There are multiple posts I found online (i.e. https://stackoverflow.com/a/51159091/6928824, https://github.com/wix/react-native-navigation/issues/648) that indicate that it should work so I don't know what I'm missing. :/
Any help is greatly appreciated! :)
One of the reasons that can cause that is using setOnNavigatorEvent in conjuction with addOnNavigatorEvent, if you have a screen wrapper component that implement addOnNavigatorEvent your current listener will not work.
As mentioned in documentation
setOnNavigatorEvent Can not be used in conjuction with addOnNavigatorEvent
Also
Bear in mind that you can't use both addOnNavigatorEvent and setOnNavigatorEvent. addOnNavigatorEvent returns a function, that once called will remove the registered handler.
I would suggest trying addOnNavigatorEvent instead of setOnNavigatorEvent
This seems to be a bug in react-native-navigation#^1.1.474 (note the caret): see my issue on GitHub.
An according pull request has been opened but not yet merged. :(

VueJS render doesn't get called

At work we are working with VueJS and we want to render one element with the contents from a 2D array. This needs 2 for loops to iterate through which isn't possible with a template. We found out we can do this with the render() function.
Our code (but simplified a bit) is:
export default {
name: 'od-table',
data() {
return {
testData: []
}
},
render() {
console.log("render function")
}
};
When we include this component in the project the render function doesn't get called. I can see the component has loaded because I can read the test-data. No logs or any other sign the render function has been called.
It could be it's an obvious mistake since we have never got this working before, but since this is something we have to use for this problem we would like to know what is wrong with the code.
Given it worked when you recreated your component file from scratch, the issue might have been that in your original file you had mistakenly left a section. That's what happened to me. If your component comes with its own <template>, it will be used for rendering and your render() function will never get called at all.
I still don't know what was wrong, but deleting the component and copying the old code in the new files seemed to solve the problem.
Any particular reason why you're using render? You might be looking for mounted.
Here is a complete list of lifecycle hooks for Vue.js 2.0. https://v2.vuejs.org/v2/api/#Options-Lifecycle-Hooks

ReactJS - render called, but DOM not updated

This has happened to me a few times. I have always managed to work around the issue, yet I am still intrigued to understand why this happens, and what I have missed.
Essentially if I have a condition within my render method which specifies the class for my div:
let divClass = this.state.renderCondition ? 'red' : 'blue';
By default I set renderCondition within my state to false.
If I then define an onClick handler on a button (as follows), and click the button, whilst render IS called, the DOM is NOT updated. That is to say the class does not change.
onClickCompile: function() {
this.setState({renderCondition: true}, function() {
synchronousSlowFunction();
});
}
This seems to have something to do with running slow synchronous code in that if the code is quick and simple the DOM IS updated appropriately.
If I wrap the call to synchronousSlowFunction in a 500 millisecond timeout, everything works as expected. I would however like to understand what I have misunderstood such that I do not need this hack.
Can you share the button onClick code? I might be wrong but this looks like an incorrectly set button onClick listener.
Make sure that onClick callback is defined without (), i.e.
<button onClick={this.something} />
instead of:
<button onClick={this.something()} />
Post more code so we can get a better (bigger) picture
synchronousSlowFunction is as you mentioned synchronous. This means, that it blocks your component while it is running. That means, that react cannot update your component, because it has to wait for the callback function to complete until it can call render with the updated values. The setTimeout wrap makes the call asynchronous, so that react can render/update your component, while the function is doing its work. It is not the time delay, that makes it work but simply the callback, which is not render blocking. You could also wrap in in a Promise or make the slow function async to prevent render blocking.
Try something Like this:
this.setState((state) => ({
...state, renderCondition: true
}));
Maybe you're doing another setState for renderCondition some where the code above should fix such things.
or maybe try using PureComponent
import React, { PureComponent } from 'react'
export default class TablePreferencesModal extends PureComponent {
render() {
return (
<div>
</div>
)
}
}
After set state use this line
this.setState({})

BackAndroid not unmounting - React Native (Android)

I am working with React Native 0.29 with Android. For a particular view/activity/screen of my app, I want to add an event listener for BackAndroid button, which is available with react native. I already have a global BackAndroid event listener added to my app (in my index.android.js file) which pop out any view from the stack if it's not the main screen.
The event listener is activated with componentDidMount() lifecycle method and it works. It override the global one and works as expected. Now the problem is, it doesn't get removed when componentWillUnmount() lifecycle method get fired. So when back from that particular screen, the event listener still remains and cause trouble. Here is what I did:
componentDidMount() {
BackAndroid.addEventListener('backBtnPressed', this._handleBackBtnPress.bind(this))
}
componentWillUnmount() {
BackAndroid.removeEventListener('backBtnPressed', this._handleBackBtnPress.bind(this))
}
I don't understand why it's not working. Please help me to understand why it's not working and what should I do to solve this issue.
I spend hours to solve this problem. I think it would help other developers if I share this.
The main problem here is with the .bind(this) statement, bind always returns a new function. So in this code, this._handleBackBtnPress.bind(this) are not same functions in addEventListener and removeEventListener. They are different functions referring different first-class objects. That's why removeEventListener is not removing the listener.
To solve this issue, we can add the following statement to our constructor method - this._handleBackBtnPress = this._handleBackBtnPress.bind(this) and remove .bind(this) from both addEventListener and removeEventListener. So our code will look something like this:
constructor(props) {
super(props)
this._handleBackBtnPress = this._handleBackBtnPress.bind(this)
}
componentDidMount() {
BackAndroid.addEventListener('backBtnPressed', this._handleBackBtnPress)
}
componentWillUnmount() {
BackAndroid.removeEventListener('backBtnPressed', this._handleBackBtnPress)
}
Now both of them will refer same function and will work as expected.

Categories

Resources