Using this.props or this.state directly vs setting const - javascript

I'm new to react and as I'm looking at examples, I see that a lot of tutorials don't use this.props or this.state directly. Instead, they will set a const at the beginning of the function. I've used the two interchangeably without seeing any difference in functionality.
Are there any gains to using const?
ie.
const {
error
} = this.state;
{error && <p>{error.message}</p>}
vs
{this.state.error && <p>{this.state.error.message}</p>}

This is called Destructuring, a feature of ES6.
There are no differences in functionality but there are little benefits of using destructuring.
First, cleaner code. If you destructure an object at the top of your code block, it appears more clear to the reader what variables you are going to use.
Second, it puts object properties in local variables which can improve performance, especially if you are using the variables multiple times like in a loop.

As you have yourself stated that there is no difference at all and it is true. My simple answer of using const is
After u define this way
const {error} = this.state;
now u can just use term (error) in the following codes instead of lengthy (this.state.error)
So it is just for simplicity

Related

Is it possible to change a const in a function? (JS)

I am trying to change a const to the preferred search engine (website linked below). Is it possible? If so, please provide a solution. Thanks!
The website: https://newtabb.gq
Website #2 (instant updates): https://newtabb.hyderite.repl.co
The code: https://replit.com/#Hyderite/newtabb (in script.js)
The code involved:
search.onclick = function() {searchQuery()};
function searchQuery() {
window.open(searchEngine + query);
}
Per the MDN Web Docs:
Constants are block-scoped, much like variables declared using the let keyword. The value of a constant can't be changed through reassignment (i.e. by using the assignment operator), and it can't be redeclared (i.e. through a variable declaration). However, if a constant is an object or array its properties or items can be updated or removed.
Per your code, the const is not an object or array so nothing about it can be changed. And if you wish to set a new value as a new variable, note you won't be able to use the same name (redeclaring it somewhere in your code).

React Native const vs let vs var in Functional Components

This is a broader question about the use of different variable declarations in react native functional components (as opposed to class components), specially the use of let vs const, and how they are effected by renders and such. For this question, when I say 'render' or 're-render' I am talking about the execution of the render function (like 'MyFunctionalComponent' below), not necessarily a UI update/change.
From my understanding, unlike plain js, a const variable is not exactly 'constant' in react/react native, and can be changed (with hooks?) like so:
export default function MyFunctionalComponent() {
const [test, setTest] = useState(false);
const testFunction = () => { //some sort of function, maybe called by a button press
setTest(true); //this can change test, but something like 'test = true' throws an error
}
}
However let can take on similar behavior from my understanding:
export default function MyFunctionalComponent() {
let test = false
const testFunction = () => { //some sort of function, maybe called by a button press
test = true;
}
}
However, most react native examples and tutorials and such I have looked at, always seem to use the const syntax, even though it seems to involve much more code. Why? Personal preference, or necessity? Does the const way of doing things somehow re-render/re-call MyFunctionalComponent with a new value for the const variable?
Next, I'm not sure the exact behavior that is causing this, but sometimes when using the const syntax inside the functional component, the variables change and save state between render calls, and sometimes, a const variable is reset to its default state every time the render is called. (I know this part is vague, so feel free to ignore it if there is not enough detail) Why does this happen?
Similarly, I have seen different behavior when consts are created outside of the functional component instead of within... does scope work as you would expect with these? Are they (still?) re-instantiated on new render calls? Does 'setState' call an re-render? Shortening the previous question, why do some of my const's preserve their state on re-renders, while some seem to reset to their defaults?
Where does var fall into this, does it act the same as in regular js, or is it affected by react as well? (I feel like I have a grasp of the differences in these variable declarations in regular js, but this const behavior with react making me question it all).
So overall the question is basically, what are the differences/advantages of let, var, and const, specifically in react/react native, and how do those differ from regular javascript?
Lastly, does it differ between class components and functional components in react native?
Thank you for reading this long question.
Personal preference, or necessity?
Preference and style only.
Using const to declare a stateful variable instead of var or let makes the intent of the code clearer. It's not necessary - pretty much all components you see would work just as well if they used var or let - but it introduces a slight possibility of confusion from those reading the code.
React is written in JavaScript. Stateful variables in React, declared with const, cannot be reassigned, just like in ordinary JavaScript. The key you're missing is that the component function is called again every time there's a re-render, resulting in the call of the useState function returning a different value.
For quick example of how this could work in vanilla JS with const and calling a function multiple times:
let i = 0;
const getI = () => i;
const fn = () => {
const theValue = getI();
console.log(theValue);
i++;
setTimeout(fn, 1000);
};
fn();
It's not that the variable gets reassigned (which would be forbidden due to the use of const), it's that the whole function runs again, resulting in a new value being assigned to the variable declared with const at the moment of its new initialization.
Next, I'm not sure the exact behavior that is causing this, but sometimes when using the const syntax inside the functional component, the variables change and save state between render calls, and sometimes, a const variable is reset to its default state every time the render is called. (I know this part is vague, so feel free to ignore it if there is not enough detail) Why does this happen?
You may be referring to the stale closure issue. This can happen if the variable binding that results in a difference being seen is from a prior render, rather than the current render.
For a quick example of what that might look like in vanilla JS, adapting from the above snippet, I'll add a timeout on the first render, which will result in only the i from the first render being used:
let i = 0;
const getI = () => i;
const fn = () => {
const theValue = getI();
console.log(theValue);
if (theValue === 0) {
// first render
setTimeout(() => {
console.log('Timeout from first render running, sees a theValue of:', theValue);
}, 5000);
}
i++;
setTimeout(fn, 1000);
};
fn();
Similarly, I have seen different behavior when consts are created outside of the functional component instead of within... does scope work as you would expect with these? Are they (still?) re-instantiated on new render calls?
Depends on what block that variable is in. If it's in another component, it may get re-initialized. If it's not in another component, then it might not be. For example, it's common to have a module that exports a component with some absolutely unchanging const values that all the components use declared up top, eg
const apiKey = 'someApiKey';
export const ApiInterface = () => {
// ...
};
With regards to const vs let and var specifically, the problem with let and var is that they permit reassignment - but the only right way to change a stateful variable in React is to call the state setter, not to reassign the variable. Calling the state setter is what will result in a re-render; reassigning a variable will not result in a re-render, and reassigning a variable will result in the assigned value being lost on the next re-render. So, it's a good idea to be perfectly clear that stateful variables should not be reassigned.
Lastly, does it differ between class components and functional components in react native?
Yes, in class components, state is held as a property of the instance (the this). The state is no longer a standalone const identifier, but a property of a larger object, so there's no const vs let vs var for stateful values in class components - unless you extract values from state and put them into normal standalone variables yourself, in which case they behave just like any other standalone variable.

"JavaScript: The Good Parts"-way to implement prototype methods?

Having read this article https://www.toptal.com/javascript/es6-class-chaos-keeps-js-developer-up and subsequently "JavaScript: The Good Parts", I shall henceforth commit to becoming a better JavaScript developer. However, one question remained for me. I usually implemented methods like this:
function MyClass(){
this.myData = 43;
this.getDataFromObject = function(){
return this.myData;
}
}
MyClass.prototype.getDataFromPrototype = function(){
return this.myData;
}
var myObject = new MyClass();
console.log(myObject.getDataFromObject());
console.log(myObject.getDataFromPrototype());
My assumption that underlies this whole post is that getDataFromObject is faster (during call, not during object creation) because it saves an indirection to the prototype but it is also less memory-efficient because every object gets an own instance of the function object. If that is already wrong, please correct me and you can probably stop reading here.
Else: Both article and book recommend a style like this:
function secretFactory() {
const secret = "Favor composition over inheritance [...]!"
const spillTheBeans = () => console.log(secret)
return {
spillTheBeans
}
}
const leaker = secretFactory()
leaker.spillTheBeans()
(quote from the article, the book didn't have ES6 yet but the ideas are similar)
My issue is this:
const leaker1 = secretFactory()
const leaker2 = secretFactory()
console.log(leaker1.spillTheBeans === leaker2.spillTheBeans) // false
Do I not mostly want to avoid that every object gets an own instance of every method? It might be insignificant here but if spillTheBeans is more complicated and I create a bazillion objects, each with twelvetythousand other methods?
If so, what is the "goot parts"-solution? My assumption would be:
const spillStaticBeans = () => console.log("Tabs rule!")
const spillInstanceBeans = (beans) => console.log(beans)
function secretFactory() {
const secret = "Favor composition over inheritance [...]!"
return{
spillStaticBeans,
spillInstanceBeans: () => spillInstanceBeans(secret)
}
}
const leaker1 = secretFactory()
const leaker2 = secretFactory()
leaker1.spillStaticBeans()
leaker2.spillInstanceBeans()
console.log(leaker1.spillStaticBeans === leaker2.spillStaticBeans) // true
console.log(leaker1.spillInstanceBeans === leaker2.spillInstanceBeans) // false
The spillInstanceBeans method is still different because each instance needs its own closure but at least they just wrap a reference to the same function object which contains all the expensiveness.
But now I have to write every method name two to three times. Worse, I clutter the namespace with public spillStaticBeans and spillInstanceBeans functions. In order to mitigate the latter, I could write a meta factory module:
const secretFactory = (function(){
const spillStaticBeans = () => console.log("Tabs rule!")
const spillInstanceBeans = (beans) => console.log(beans)
return function() {
const secret = "Favor composition over inheritance [...]!"
return{
spillStaticBeans,
spillInstanceBeans: () => spillInstanceBeans(secret)
}
}
}())
This can be used the same way as before but now the methods are hidden in a closure. However, it gets a bit confusing. Using ES6 modules, I could also leave them in module scope and just not export them. But is this the way to go?
Or am I mistaken in general and JavaScript's internal function representation takes care of all this and there is not actually a problem?
My assumption that underlies this whole post is that getDataFromObject is faster to call than getDataFromPrototype because it saves an indirection to the prototype
No. Engines are very good at optimising the prototype indirection. The instance.getDataFromPrototype always resolves to the same method for instances of the same class, and engines can take advantage of that. See this article for details.
Do I not mostly want to avoid that every object gets an own instance of every method? It might be insignificant here
Yes. In most of the cases, it actually is insignificant. So write your objects with methods using whatever style you prefer. Only if you actually measure a performance bottleneck, reconsider the cases where you are creating many instances.
Using ES6 modules, I could also leave them in module scope and just not export them. But is this the way to go?
Yes, that's a sensible solution. However, there's no good reason to extract spillInstanceBeans to the static scope, just leave it where it was - you have to create a closure over the secret anyway.
The spillInstanceBeans method is still different because each instance needs its own closure but at least they just wrap a reference to the same function object which contains all the expensiveness.
It should be noted that you're just replicating the way the JavaScript VM works internally: a function like spillTheBeans is compiled only once where it occurs in the source code even if it has free variables like secret. In SpiderMonkey for example, the result is called a »proto-function« (not to be confused with prototype). These are internal to the VM and cannot be accessed from JavaScript.
At runtime, function objects are created by binding the free variables of proto-functions to (a part of) the current scope, pretty much like your spillInstanceBeans example.
Saying that, it's true that using closures instead of prototype methods and this creates more function objects overall – the robustness gained from true privacy and read-only properties might make it worthwhile. The proposed style focuses more on objects rather than classes, so a different design could emerge that cannot be compared directly to a class-based design.
As Bergi says, measure and reconsider if performance is more important in (some part of) your code.

Passing an => that calls a func instead of just passing the func itself

I'm giving myself a bit of a crash course on JavaScript so that I can learn React. I haven't done any dev work for many years so this may be a facepalm moment.
I am reading a blog post on useState(). I understand that if the parameter passed to useState() is a function, the function is only executed on the first render execution.
(EDIT: blog post is here https://blog.logrocket.com/a-guide-to-usestate-in-react-ecb9952e406c/)
However, this confuses me:
const Message= () => {
const messageState = useState( () => expensiveComputation() );
/* ... */
}
In this example, why not just pass expensiveComputation to useState() like so?
const Message= () => {
const messageState = useState( expensiveComputation );
/* ... */
}
There are also some weird niggles about functions in Javascript that I don't think I'm understanding. For example, I've heard that arrow functions are executed when they are defined, but I've played with JSBin and I can't manage to prove that to myself in any way.
Thanks for the help!
I think these are the same in this particular case. The more general issue is the binding of this.
() => this.foo()
and
this.foo
are not the same, because "this" stays attached to the class in the first case and gets lost in the second case, so that when "foo()" is called in the second case, it won't be accessing the correct object as its "this".
It's generally regarded as a major design mistake of Javascript that this can be easily lost. The older-JS way to preserve this is with the bind method, i.e. this.foo.bind(this). But in language design, it's not possible to redefine the meaning of code without breaking everyone's existing applications. When lambdas with => were introduced, this was handled in the more modern, lexical way that preserves this.

Difference between class and function blocks in React?

I was going through an article on Commonly faced problems with React and there i found this example.
class Numbers extends React.Component {
const arrayOfNumbers = _.range(1, 10);
// ...
}
It said "The code above is invalid because inside the body of a JavaScript class you don’t have the freedom of doing just about anything. You can only define methods and properties using limited syntax.
This is a bit confusing because the {} used in the class syntax looks like the plain-old block scope, but it’s not.
Inside a function-based component, you DO have the freedom of doing just about anything"
// Totally Okay:
const Number = (props) => {
const arrayOfNumbers = _.range(1, 10);
// ...
};
Can anyone explain to me why the above statement inside the class body is invalid ?? And what is that strange looking _. symbol ??
Can anyone explain to me why the above statement inside the class body is invalid ??
That's just the way the syntax for classes is. You can define functions in the body of the class, and they'll go on the prototype. If you want any instance variables, you do those in the constructor.
And what is that strange looking _. symbol ??
It's a variable named _. In this case, it's almost certainly a reference to the Lodash library, a commonly used library with utility functions.

Categories