For Example,
We could just use
onClick={(foo)}
or something else.. instead of
onClick={this.foo.bind(this)}
Just curious if there is any particular technical constraint.
Let me answer the question from a design/philosophical perspective, instead of a technical one (the other answers do that pretty well already).
React COULD have, there would be no problem to that. But why have multiple ways to do things when you can have one (React tries to stay as close to ES standards as possible). If there are multiple ways to do a single task, it'll affect readability across codebases, making it harder for developers to ease into a codebase since they would have to unravel layers upon layers of abstraction till they gets to the core idea.
Basically, I think it was a design choice to NOT add a lot of the syntactic sugar that could have been added (JSX itself is already a form of syntactic sugar, we don't need syntactic sugar on our syntactic sugar).
From the React Docs:
"In general we resist adding features that can be implemented in userland. We don't want to bloat your apps with useless library code. However, there are exceptions to this."
"We prefer boring code to clever code. Code is disposable and often changes. So it is important that it doesn't introduce new internal abstractions unless absolutely necessary."
Source: https://facebook.github.io/react/contributing/design-principles.html
Representing the ideas from this talk: https://www.youtube.com/watch?v=4anAwXYqLG8
onClick={foo} is something completely different to onClick={this.foo.bind(this)}, and parentheses are required for maths.
.bind causes a new function to be created on every single invocation, so this would not be very performant.
(I assume) an aim of JSX to try and be as close to regular JS as possible so it's easy to pick up.
It is not the realm of JSX to add new language elements; a bind operator is most definitely a new language element.
If you notice, JSX doesn't provide any new language constructs other than what is necessary to call React.createElement. Additionally, you probably wouldn't want to use .bind like this anyway due to fact it's creating a new function every time. Finally, the parens are required for mathematical operations - you couldn't use {()} because what if I wanted to use a mathematical operation like {(a + b) * c}? Any interpolation that JSX does must be a JavaScript expression, currently, so unless JavaScript itself supports this syntax it's unlikely the interpolation will too.
You may be interested in the function bind operator, but I'd recommend you avoid using bind in this manner; instead, bind the functions once in the component constructor, like so:
class MyComponent extends Component {
constructor() {
this.boundOnClick = this.onClick.bind(this)
}
render() {
return <button onClick={this.boundOnClick}>Foo</button>
}
}
// with function bind operator
class MyComponent extends Component {
constructor() {
this.boundOnClick = ::this.onClick
}
render() {
return <button onClick={this.boundOnClick}>Foo</button>
}
}
This ensures you only create the bound function once. For stateless components, you don't have access to this anyway so there's no need to use bind.
If JSX were to introduce an alternative syntax to this, I personally would be opposed to it, though if they could overcome the limitations I've mentioned above, there's nothing technically stopping them.
It is more a problem with ES6 which does not have automatic binding of "this" to class methods. In ES7, there is a proposal to introduce a new operator ::. With ES7, you could write:
onClick={this::foo}
Related
I'm working on a large react app where performance matters.
At first I avoided using objects properties inside useMemo dependencies (I was avoiding dot notation inside dependencies). But I have seen this in react's documentation so I think it is safe.
Now my linter sometimes complains when I don't include optional chaining inside the dependencies, and I end up doing this:
const artworks = useMemo(() => {
let list = availableArtworks.artworks;
if (route.params?.artworkId) {
// Some Stuff here
}
return list;
}, [availableArtworks, route.params?.artworkId]);
It looked dirty to me at first but now I'm considering starting to use it. If route has no params property, then the whole route.params?.artworkId expression should be falsy, right? Then if the object changes, and we suddenly have a params and artworkId the useMemo should reexecute and take that value into account?
So my question is: Is it safe to use it like so or is it dirty in any ways ?
Syntax wise
Looks safe. The one line I worry about is:
let list = availableArtworks.artworks;
If the key "artworks" isn't a primitive, you might modify it without intending to.
Also, your dependencies array should look like:
[availableArtworks?.artworks, route.params?.artworkId]);
Do you really need useMemo?
Lastly, if performance is super important, I would definitely reconsider (and measure) if you do need the useMemo. useMemo is for heavy computational lifting. Do you have some recursion happening? Some intensive calculation? Factorials? Long Loops? If the answer is no, bringing useMemo will in fact decrease performance.
Recommend you to read this article from Kent C. Dodds (Author of react-testing-library and remix) about performance.
Some of my code got a review comment saying something like "move const outside the function to avoid redeclaration". This was a normal function component, something like this:
export default function someComponent() {
const someString = 'A string';
///...
}
I was confused about the idea of this causing a redeclaration, because it does not, I know that the record that holds the variables and constants belong to the scope, so it's not exactly that.
But then i remembered that typescript does not allows you to have a const inside a class, not sure about the reason or is this is related. But then ts added the readonly modifier in ts v2, so the confusion remains.
Should const be outside function components, or not?
I would love to know more opinions.
There are 2 sides to the coin. Firstly, in terms of clean code and readability, I strongly prefer local declarations like in your example. I would love using more nested functions as well.
However, in JavaScript, every time the function executes, the local definitions will be redeclared, even if they are constants or functions. So it's a trade-off. If the function is called many times, this becomes an overhead.
I think it would not be hard for a compiler like TypeScript's tsc or some other pre-processor to extract those definitions at compile time to have best of both worlds. But it's likely that they do not do this to remain fully compatible. I am not aware of such tools but would be interested if there are some.
Consider an example:
const someElement = <CustomElement value="some" />;
function Foo({ style }) {
return <Bar style={style}>{someElement}</Bar>;
}
Are there any pitfalls if I want to keep passing the same instance of React element as props to children? How normal and acceptable is this specific case for React's reconciliation?
I suspect that your approach is sound. Then again, I'm not sure this will solve your problem; it still has to calculate someElement. I would consider using truly static data (e.g. literal HTML) and I believe React has specific facilities for that (dangerouslySetInnerHTML?). Also, note that when Bar updates it still has to do a DOM compare all the way down the tree. It would not seem that it could know there's something special about someElement that would obviate the need to compare that part of the DOM tree. I think you'd need to at least give the outer tag of your literal a key but this key needn't change unless you repeat the stuff as siblings. This approach seems fraught even though it may be technically sound.
Another approach that might work is to make it a traditional component but override the method that tells it whether it needs to update. Obviously, it never needs to update but it would still incur the cost of the initial calculation of the DOM. I believe your suggestion still incurs that cost, as well. Maybe a component that does nothing but dangerouslySetInnerHTML and refuses all updates could do the trick; zero calculation.
I have an angular 1.4 project on typescript, the project is getting bigger and bigger and our team is really tired of interfaces that we have declared (so that all objects are typed, in comparison to any)
I'm asking if this is a good idea or not? I chose typescript because I wanted to have a typed project, should I drop the interfaces or not?
You can get by without using interfaces and going with any, but in the long term you are probably going to regret it. If your team is sick of the interfaces you've created, I would put time in fixing those instead of abandoning them. There is a significant argument around if typed languages reduce the number of errors found in code. Personally, I think they do.
What I've found with typed languages is that it helps remove stupid mistakes we all make, and this clears up our time to focus on actual logic problems in code. Not everyone agrees with me on this, but I will always pick a type language over a non typed one, especially if the team is used to dealing with languages like Java or C#.
Interfaces can be very helpful if used properly.
If you are just doing this....
IFoo { ... }
Foo implements IFoo { ... }
Then they will not help as much as they do in other typed languages (C#/Java). Because the type checking in TypeScript is dependent upon the properties on the object and NOT on the declared type. This is because you can simply write this...
MyCtrl (foo: Foo) { ... }
//instead of
MyCtrl {foo: IFoo) { ... }
This will not hinder unit testing in any way since as stated above the type checking is based upon properties and not declarations.
There are cases when interfaces can be quite helpful, for instance a common use case is when defining an object as a parameter...
doSomething (options: ISomethingOptions) { ... }
There is no harm in creating interfaces for everything, you just need to determine what level of typing works best for your team.
I write code in C. I have been striving to write more testable code but I am a little
confused on deciding between writing pure functions that are really good for testing
but require smaller functions and hurt readability in my opinion and writing functions
that do modify some internal state.
For example (all state variables are declared static and hence are "private" to my module):
Which of this is more testable in your opinion:
int outer_API_bar()
{
// Modify internal state
internal_foo()
}
int internal_foo()
{
// Do stuff
if (internal_state_variable)
{
// Do some more stuff
internal_state_variable = false;
}
}
OR
int outer_API_bar()
{
// Modify internal state
internal_foo(internal_state_variable)
// This could be another function if repeated many
// times in the module
if (internal_state_variable)
{
internal_state_variable = false;
}
}
int internal_foo(bool arg)
{
// Do stuff
if (arg)
{
// Do some more stuff
}
}
Although second implementation is more testable wrt to internal_foo as it has no sideeffects but it makes bar uglier and requires smaller functions that make it hard for the reader to even follow small snippets as he has to constantly shift attention to different functions.
Which one do you think is better ? Compare this to writing OOPS code, the private functions most of the time use internal state and are not pure. Testing is done by setting up internal state on a mock object instance and testing the private function. I am getting a little confused on whether to use or whether to pass in internal state to private functions for the sake of "testability"
Whenever writing automated tests, ideally we want to focus on testing the specification of that unit of code, not the implementation (otherwise we create fragile tests that will break whenever we modify the implementation). Therefore, what happens internally in the object should not be of concern to the test.
For this example, I would look to build a test that:
Executes the test by calling outer_API_bar.
Asserts that the correct behavior of the call using other publicly accessible functions and/or state (there must be some way of doing this, as if the only side effect of calling outer_API_bar was internal to this unit of code, then calling this function could not impact your wider application in any way, and essentially be useless).
This way, you are able to keep the fact that you use functions like internal_foo, and variables like internal_state_variable as implementation details, which you can freely change when refactoring your code (i.e. to make it more readable) without having to change your tests.
NOTE: This suggestion is based on my own personal preference for only testing public functions, and not private ones. You will find much debate on this topic where some people pose good arguments for testing private functions being a valid thing to do.
To answer your question very specifically pure functions are waaaaay more 'testable' than any other kind of abstraction. The more pure functions you can include, the more testable your code would be. As you rightly mention, this can come at the cost of readability, and I am sure there are other trade offs to consider. My suggestion would be to aim for more pure functions and look for other techniques that would allow you to compensate on the readability side of things.
Both snippets are testable via mocks. The second one, however, has the advantage that you can also check the argument of internal_foo(bool arg) for an expected value of true or false when the mock for internal_foo() is invoked. In my opinion, that would make for a more meaningful test.
Depending on the rest of the code that we don't know, testing without mocks may be more difficult.