I know that there are already some threads about that, but I was not able to find an actual one.
So my question is, should I always use the bind approach or the arrow functions?
What are the pros/cons of them in 2020? From what I read I know, that (at least in 2018) the bind methods had a better performance.
Another question: Should I just bind the functions, which I call use in the render method via a click?
Here a small example
constructor(super) {
props(super)
this.firstBind = this.firstBind.bind(this);
this.secondBind = this.secondBind.bind(this;
}
render() {
return (
<Button title="First Bind" onClick={this.firstBind} />
<Button title="First arrow" onClick={this.firstArrow} />
)
}
firstArrow = () => {
//some outout
}
secondArrow = async() => {
//fetch some data from a database and output it
}
secondBind() {
//some output
}
async secondBind() {
//fetch some data from a database and output it
}
My goal is to understand it completely.
Thanks a lot!
Jan
You are right, this question has been asked many times before and it will likely be closed because it has so many duplicates, but I will provide a short answer anyways.
Bind and arrow functions achieve the same in a React component
On a more technical level binded functions and arrow functions are different, but for the react world which you are talking about, they are the same, the simply create a function which is bound to the context of the instance that created them, so you can access the instance variables when they execute.
But why then is there two ways to create binded functions?
Why then, would you ask, go through the trouble of having two ways of creating context-binded functions? well, even though they achieve the same you can tell that that the .bind version is more verbose and also prone to error, as you might forget to bind the functions on the constructor, therefore it is considered good practice to use arrow functions.
The react team did not create them, they are a part of javascript and having to bind functions is just a consequence of the underlaying design of the language, React only forces you to bend javascript to properly work as an OOP language.
Ok, so what should you do?
That being said, the react ecosystem is moving towards hooks, and even though the team responsible for react keep repeating one does not need to use hooks, the tendency is clear, class components will disappear, ex: as libraries update to use hooks and maintaining to different ways of accessing them is too much trouble, most of them use hooks only.
So TL:DR in 2020: this question is no longer relevant, go use functional components with hooks and you will have no problems
Related
I'm working on unit testing all of my components, and I've hit a bit of a snag (or maybe a misunderstanding of how to properly test).
I have a component that receives some parameters from the store, and then calls a series of functions that mostly return an input string with some transformations applied.
This looks something like the following:
<script setup lang="ts">
import { someTextTransform } from '../utilities/someTextTransform';
...
let parsedText = store.input;
if (store.applySomeTextTransform) {
parsedText = someTextTransform(parsedText);
}
I have already tested these functions themselves, so to me it seems like testing the actual output of the calls is unnecessary and I instead could just test to see if the functions have been called.
Here is a snippet on spying from the Vitest docs
Mocking functions can be split up into two different categories; spying & mocking.
Sometimes all you need is to validate whether or not a specific function has been called (and possibly which arguments were passed). In these cases a spy would be all we need which you can use directly with vi.spyOn().
This is exactly what I want. I want only to know whether or not the function has been called. The functions themselves are simple enough that they do not require additional setup (i.e., mocking is not required).
However looking through the docs of Vue Test Utils I don't see a way to do this. It looks like a more common way to do this is to mock the functions first and then you can spy on them more easily, but then I would have to create mocks that don't actually mock the functions which seems like I'm adding code to my codebase for no benefit other than a weird workaround.
I may just be missing something on how to do this, but I might also be approaching the testing in a suboptimal way so any advice is appreciated.
I have the following desing in DDD
Post Aggregate with
Body: HTML of the post
Banner entity with
Html: HTML of the banner
The Banner entity belongs to Post aggregate, so I want to create a method BodyWithBanners in the Post aggregate.
The point of this method will be to search into the HTML of the Post.Body and insert the HTML of the Banner.
So far, so good.
However I have intention of reuse this functionallity in abstract: "Insert some HTML inside another HTML". So I'm creating a diffent class for doing that: BannerReplacer
Here comes the problem, how should I invoke this new class?
Just create an instance inside the Post.BodyWithBanners method (breaking Dependency Injection)
Passing the BannerReplacer in the constructor of the Post aggregate (This can be a nightmare for creating Post instances)
Passing the BannerReplacer to the BodyWithBanners method (which implies the client using Post must handle the BannerReplacer)
I have chosen for now the first option, but I don't feel really confortable with it, I believe there must be a better way of doing this.
I have chosen for now the first option, but I don't feel really comfortable with it, I believe there must be a better way of doing this.
Much of the time, the first option is fine -- so you should practice being comfortable with it. That mostly means thinking more about what dependency injection is for, and having a clear picture in your mind for whether or not those forces are at play here.
If Banner is an entity, in the domain-driven-design sense, then it is probably something analogous to an in memory state machine. It's got a data structure that it manages, and some functions for changing that data structure, or answering interesting questions about that data structure, but it doesn't have I/O, database, network etc concerns.
That in turn suggests that you can run it the same way in all contexts - you don't need a bunch of substitute implementations to make it testable. You just instantiate one and call its methods.
If it runs the same way in all contexts, then it doesn't need configurable behavior. If you don't need to be able to configure the behavior, then you don't need dependency injection (because all copies of this entity will use (copies of) the same dependencies.
When you do have a configurable behavior, then the analysis is going to need to look at scope. If you need to be able to change that behavior from one invocation to the next, then the caller is going to need to know about it. If the behavior changes less frequently than that, then you can start looking into whether "constructor injection" makes sense.
You know that you intend to use a single BannerReplacer for a given method invocation, so you can immediately start with a method that looks like:
class Banner {
void doTheThing(arg, bannerReplacer) {
/* do the bannerReplacer thing */
}
}
Note that this signature has no dependency at all on the lifetime of the bannerReplacer. More particularly, the BannerReplacer might have a longer lifetime than Banner, or a shorter one. We only care that the lifetime is longer than the doTheThing method.
class Banner {
void doTheThing(arg) {
this.doTheThing(arg, new BannerReplacer())
}
// ...
}
Here, the caller doesn't need to know about BannerReplacer at all; we'll use a new copy of the default implementation every time. Caller's that care which implementation is used can pass in their own.
class Banner {
bannerReplacer = new BannerReplacer()
void doTheThing(arg) {
this.doTheThing(arg, this.bannerReplacer)
}
// ...
}
Same idea as before; we're just using an instance of the BannerReplacer with a longer lifetime.
class Banner {
Banner() {
this(new BannerReplacer())
}
Banner(bannerReplacer) {
this.bannerReplacer = bannerReplacer;
}
void doTheThing(arg) {
this.doTheThing(arg, this.bannerReplacer)
}
// ...
}
Same idea as before, but now we are allowing the "injection" of a default implementation that can outlive the given instance of Banner.
In the long term, the comfort comes from doing the analysis to understand the requirements of the current problem, so that you can choose the appropriate tool.
Overview:
I refactoring script tests before I was used Enzyme to test, but now, I want to use #testing-library/react
Problem:
I can't find a solution for setState in #testing-library/react
Using setState is dangerous approach regardless testing library used.
It depends on implementation details(say, property names inside the state) so it becomes much harder to maintain tests - more tests to change, easy to get test broken when app is fine etc.
You cannot call that once you convert class component to functional one with hooks. So you depends on implementation details even more.
And finally direct state manipulation may end with state you would never get in real world. This means your component will be broken because it's impossible to reach some state but your tests with direct initialization will be fine.
So what you better do? Provide props, change props, call props(wrapper.find('button').filter(button => button.text() === 'Cancel').props().onClick() for enzyme, fireEvent.click(getByText(/Cancel/i)) for RTL) and verify against what's rendered.
This way your tests will be shorter, most actual and need less changes after you update component under test.
I want to create a Perl 6 module that would "export" a LEAVE phaser to the scope in which the use statement is placed. I have not found a way to do that.
I assume this would need to be done inside an EXPORT sub, but how? The default functionality of an EXPORT sub is to just return a Map with name => object mapping of things to export. As far as I know, there's no way to introspect what the outer scope is. Or am I missing something?
Thanks to Zoffix++ for pointing out a very hacky way of doing this.
sub EXPORT() {
$*W.add_phaser: $*LANG, 'LEAVE', { code you want to run }
{} # need to show that we're not exporting anything
}
This hack depends on various Rakudo internals, and is therefore not recommended to be used "in the wild". And it's quite likely that a better, more supportable way will be implemented for this functionality in the near future.
This hack was needed for a module that supports a sort of timely destruction other than from the direct scope in which an object is created (aka LEAVE phaser). This is typically handled in Perl 5 by using reference counting and calling DESTROY if the reference count of an object goes to 0.
This module can now be found in the Perl 6 ecosystem: FINALIZER. This module allows module developers to mark created objects for finalization: by default on program exit. Or from a scope indicated by the client program.
Not sure this is possible, but other people might know more. But what are you after anyway? I had a similar desire a while ago, I wanted to do something like a RAII lock. I solved it by wrapping the block rather than putting the LEAVE into it directly:
sub mtest($block) { LEAVE { say "hoo" }; $block() }
mtest { say "woo"; }
Perhaps that works for you as well...
When using m.module, I often would like to provide arguments to the controller constructor so that the first rendering starts with the right data. However, the Mithril documentation and examples always show module.controller() and module.vm.init() without parameters.
To go around this issue and have module.controller(initData) I've resorted to use this small utility function to wrap and extend the existing m.Module:
var mModule = function (dom, mod, arg) {
return m.module(dom, {
view: mod.view,
controller: mod.controller.bind(mod.controller,arg)
});
};
Questions:
Is this an anti-pattern? Is there an alternate recommended way instantiate the module with custom external data?
Would this cause issues with m.route? I saw some mentions of recursive calls in the source code but could not get my head around it.
Following the 2 points above, is the lack of parameter for m.module a deliberate design choice?
Oh...and thanks to all involved for the existing documentation and discussions.
No, it's not an anti-pattern, and it's an idea that is explored in one of the blog articles, and also by Moria (a router extension library for Mithril)