purpose of # operator in javascript/ [duplicate] - javascript

I'm looking at some ES6 code and I don't understand what the # symbol does when it is placed in front of a variable. The closest thing I could find has something to do with private fields?
Code I was looking at from the redux library:
import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'redux/react';
import Counter from '../components/Counter';
import * as CounterActions from '../actions/CounterActions';
#connect(state => ({
counter: state.counter
}))
export default class CounterApp extends Component {
render() {
const { counter, dispatch } = this.props;
return (
<Counter counter={counter}
{...bindActionCreators(CounterActions, dispatch)} />
);
}
}
Here is a blog post I found on the topic: https://github.com/zenparsing/es-private-fields
In this blog post all the examples are in the context of a class - what does it mean when the symbol is used within a module?

I found the accepted answer was not enough to help me sort this out, so I'm adding a little more detail to help others who find this.
The problem is that it's unclear exactly what is the decorator. The decorator in the example given is not just the # symbol, it's the #connect function. Simply put, the #connect function is decorating the CounterApp class.
And what is it doing in this case? It's connecting the state.counter value to the props of the class. Remember that in redux the connect function takes two arguments: mapStateToProps and mapDispatchToProps. In this example, it's taking only one argument - mapStateToProps.
I haven't investigated this too much, but this appears to be a way to encapsulate your state-to-props and dispatch-to-props mappings so they accompany your components rather than being located in a different file.

It's a decorator. It's a proposal to be added to ECMAScript. There are multiple ES6 and ES5 equivalent examples on: javascript-decorators.
Decorators dynamically alter the functionality of a function, method, or class without having to directly use subclasses or change the source code of the function being decorated.
They are commonly used to control access, registration, annotation.

What is #myDecorator()?
The # symbol in javascript stands for a decorator. Decorators are not present in ES6 so the in code you are working with the decorator is probably transpiled to an version of javascript which can be run in any browser.
What is a decorator?
A decorator extends (i.e. decorates) an object’s behavior dynamically. The ability to add new behavior at runtime is accomplished by a Decorator object which ‘wraps itself’ around the original object. A decorator is not just a concept in javascript. It is a design pattern used in all object oriented programming languages. Here is a definition from wikipedia:
In object-oriented programming, the decorator pattern is a design
pattern that allows behavior to be added to an individual object,
dynamically, without affecting the behavior of other objects from the
same class. The decorator pattern is often useful for adhering to the
Single Responsibility Principle, as it allows functionality to be
divided between classes with unique areas of concern
Why use a decorator?
The functionality of an object can be modified at runtime when using a decorator. For example, in your code you simply imported the decorator and added it to your CounterApp class. Now your CounterApp has dynamically added functionality Without you knowing the implementation details.
Example:
// decorator lights is a function which receives the class as an argument
let lights = function(tree) {
// The behaviour of the class is modified here
tree.treeLights = 'Christmas lights'
}
#lights // the decorator is applied here
class ChristmasTree {}
console.log(ChristmasTree.treeLights); // logs Christmas lights

Related

Custom hook that only returns helper functions

I made a custom hook that only returns helper functions. Nowhere in the custom hook do I use another hook (useState, useEffect...)
Example:
import backend from '../lib/backend';
import axios, { AxiosError } from 'axios';
interface PresignedData {
fields: any;
url: string;
key: string;
}
type Resource = 'users' | 'events';
function useBucket() {
const uploadViaPresignedPost = async function (
resource: Resource,
file: File
) {
...
};
const buildImageUrl = function (key: string) {
return `${process.env.NEXT_PUBLIC_S3_BUCKET_DOMAIN}/${key}`;
};
return { uploadViaPresignedPost, buildImageUrl };
}
export default useBucket;
Is this common practice? Or would it be better to create a class with static methods? export helper functions from separate file? What is best practice?
Using a class for this wouldn't make all that much sense because a class is meant for when you need to tie together data associated with an instance with methods that can operate on that data. If there's no data associated with an instance - if the class never has new called on it - then there's not much point to a class in the first place. A few plain functions or a plain object with functions in it would make more sense than a class.
Your current approach of a custom hook that doesn't use any other hooks inside it seems a bit weird, but it's not forbidden. Feel free to use that approach if you want. Using a custom hook has an added benefit that if you later decide to change the logic and, for example, feel the desire to add a useState or useEffect or something to the custom hook, it's trivial to add them into the custom hook. In contrast, if you used anything other than a custom hook and later found that you needed to add something that required hook logic, you would not be able to without first refactoring everything back into a custom hook again.

Scope of an imported variable in ionic v3 [duplicate]

I have a constants file constants.ts:
export const C0NST = "constant";
I access it in a service some.service.ts like so:
import { C0NST } from './constants';
console.log(C0NST); // "constant"
However, when I access it in a component template:
some.component.ts:
import { C0NST } from './constants';
some.component.html:
{{ C0NST }} <!-- Outputs nothing -->
However defining a member in the component class works:
some.component.ts
public const constant = C0NST;
some.component.html
{{ constant }} <!-- constant -->
I don't understand why I was able to access the imported constant directly in the service class but not in the component template even though I imported it in the component class.
In Angular2, the template can only access fields and methods of the component class. Everything else is off-limits. This includes things which are visible to the component class.
The way to go around this is to have a field inside the component, which just references the constant, and use that instead.
It's one limitation of the design, but perhaps you should think a bit more about why you need a constant in the template in the first place. Usually these things are used by components themselves, or services, but not the template.
Since in the Component's template you can only use attributes of the Component's class, you can't directly use any external constants (or external variables).
The most elegant way that I've found so far is the following:
import { MY_CONSTANT } from '../constants';
#Component({
// ...
})
export class MyTestComponent implements OnInit {
readonly MY_CONSTANT = MY_CONSTANT;
// ...
}
which basically just creates a new attribute MY_CONSTANT inside the component class. Using readonly we make sure that the new attribute cannot be modified.
Doing so, in your template you can now use:
{{ MY_CONSTANT }}
The scope of Angular2 template bindings is the component instance. Only what's accessible there can be used in bindings.
You can make it available like
class MyComponent {
myConst = CONST;
}
{{myConst}}
There are two best directions in my opinion:
Wrapping constants as internal component property
enum.ts
export enum stateEnum {
'DOING' = 0,
'DONE',
'FAILED'
}
component.ts
import { stateEnum } from './enum'
export class EnumUserClass {
readonly stateEnum : typeof stateEnum = stateEnum ;
}
Example uses enum, but this can be any type of defined constant. typeof operator gives you all of benefits of TypeScript typing features. You can use then this variable directly in templates:
component.html
<p>{{stateEnum.DOING}}<p>
This solution is less efficient in memory usage context, because you are basically duplicating data (or references to constants) in each component you wish to use it. Beside that, syntax
readonly constData: typeof constData = constData
in my opinion introduce a lot of syntax noise and may be confusing to newcommers
Wrapping external constant in component function
Second option is to wrap your external variable/constant with component function and use that function on template:
enum.ts
export enum stateEnum {
'DOING' = 0,
'DONE',
'FAILED'
}
component.ts
import { stateEnum } from './enum'
export class EnumUserClass {
getEnumString(idx) {
return stateEnum[stateEnum[idx]];
}
}
component.html
<p>{{getEnumString(1)}}</p>
Good thing is that data is not duplicated in controller but other major downside occur. According to Angular team, usage of functions in templates is not recommended due to change detection mechanism, which works way less efficient in case of functions returning values to templates: change detection have no idea does value return by a function has changed, so it will be called way often than needed (and assuming you returning const from it, it's actually needed only once, when populating template view. It may be just a bit efficiency killing to your application (if you are lucky) or it may totally break it down if function resolves with Observable for instance, and you use async pipe to subscribe to results. You can refer to my short article on that HERE
You can create a BaseComponent , it is a place where you should create your constant instances and then you can create your FooComponent extends BaseComponent and you can use your constants.

Can I make a functional component in Hyperstack?

All of the documentation refers to creating components using classes. Can I make a functional component in order to leverage react hooks, and if so, how?
To clarify, I can only find documentation for creation a class based component like
class Example < HyperComponent
render do
DIV { "Example" }
end
end
Which would be equivelent to
class Example extends React.Component {
render() {
return <div>Example</div>
}
}
I want to recreate the following:
() => {
return <div>Example</div>
}
No, you cannot. See https://github.com/hyperstack-org/hyperstack/issues/167 for why. Basic answer: the Hyperstack DSL already solves the major issues solved by functional components, and the negatives of adding functional components (there are some) then outweigh any advantages.
Note that you can import functional components from JS libraries just fine.
example = Example().as_node
# then you can do
example.render
# or anything else you want with the example object
Another(example_component: example) # to pass it as a param

Using Mobx inject store with Typescript and React stateless component [duplicate]

I'm converting a react project from redux to mobx, and I'm having the following problem: I was using the container/presenter pattern with redux, which meant using the redux "connect" function, like this:
export default connect(mapStateToProps, mapDispatchToProps)(Leads);
The problem I'm having is that there's no equivalent mobx function, so instead, I tried to simply create an instance of the component in the container. Something like:
render() {
return (
<MyComponent
store={mystore}
/>
);
}
Unfortunately, that doesn't work, because MyComponent has injected properties from react-router, something like this:
class MyComponent extends React.Component<ReportProps & RouteComponentProps<ReportProps>> {
constructor(public routeProps: ReportProps & RouteComponentProps<ReportProps>) {
super(routeProps);
}...
I tried getting rid of the container concept, but the same problem occurs in other places because I'm using the mobx-react #inject decorator. For example, I have a component like this:
export interface AddressProps {
report: IReportStore;
}
#inject((rootStore: RootStore) => ({
report: rootStore.report
}))
#observer
class Address extends React.Component<AddressProps> {
...
If I then try to use my component somewhere, typescript complains that I'm not passing the required property (report, in this instance), even though I shouldn't need to, since I'm injecting the properties.
I figure I must be missing something basic, as this is a fairly straightforward use of mobx. Or maybe it's just a typescript problem...? If so, any ideas how to fix or work around it?
Thanks in advance,
Jonathan
There are a lot of problems around the mobx inject method.
the original idea was to return a Partial<TProps> but you can't do this typed without losing your original Class: React.Component<Partial<TProps>,TState> != YourComponent - the set properties.
Read the discussed problem here: https://github.com/mobxjs/mobx-react/issues/256
Simplistic solution
Use optional parameters in props and set them in a getter property:
interface AppProps {
store?: SDtore;
}
class App {
get store(): TimeEntryStore {
return this.props.store as Store;
}
method(){
this.store;///
}
}
Other solution
If you want to keep your required parameters (eg: for using the component outside of mobx etc).
You can consider casting the component to React.Component<TPropsReduced,State> where TPropsReduced is a self defined interface with required props after injected.
The downsides are:
Losing type safety at casting (eg if you make mistakes/typo's in the interface properties. (can be solved by extending/subclassing interfaces.
Losing methods calls. You will no longer have typed methods on the component (eg: when you use ref={()=>}), but using this is dis-advised anyways.
Example:
interface AddressPropsMobx {
}
interface AddressProps extends AddressPropsMobx {
report: IReportStore;
}
//Pure react component
class Address extends React.Component<AddressProps> {}
// Mobx version:
const MobxAddress = inject((rootStore: RootStore) => ({
report: rootStore.report
}))(observer(Address)) as React.Component<AddressPropsMobx>; //unsafe cast

How to modularize JavaScript class (pull methods out of main file, import methods into main file)

Is it possible to pull class methods out of the class in JS? Forgive me, I am functional paradigm, so using React forces me to use classes and this keyword (so far anyway). Some of my components are getting large and I do not want this.
I can't find anything on Google about pulling methods out or modularizing a class.
Is there a way I can just say "get this method from './some_method.js' and use it as if it was declared inside this file&class" without much invasive changes?
Failing that, I'm hypothesizing about making them all functions and pass this into them. That feels pretty dirty, however.
I'd appreciate some guidance to what keywords I need to be looking at, or simply how to move methods out so I don't have 2000 line files that take me 20 minutes to find
toggleFullMenu() {
this.setState({ menuOpen: !this.state.menuOpen})
}
without pressing CTRL+F. That is my motivation.
I'd also like to know if there are any pro tips about this as relates to constructors. Any warnings from the class inheritance paradigm folks? I simply want the methods to sit by themselves in separate files, but I don't know what I'm looking for. I've never seen people talking about this.
Edit, I just found this in the MDN:
Sub classing with extends
The extends keyword is used in class declarations or class expressions to create a class as a child of another class.
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.');
}
}
Is this what I need? How would I go about pulling a bunch of extensions in? I don't want a child class though, that doesn't sound like what I am describing.
You can do so using Function.prototype.bind, so that you have control of the value of this.
In one module, you can export the "method" as a regular function:
// methods.js
export const toggleFullMenu = () => {
this.setState({ menuOpen: !this.state.menuOpen })
}
And in your component module:
import React from 'react'
import { toggleFullMenu } from './methods'
class SomeComponent extends React.Component {
constructor () {
super()
this.toggleFullMenu = toggleFullMenu.bind(this)
}
render () {
return <button onClick={this.toggleFullMenu}>Click Me</button>
}
}
The toggleFullMenu function could be bound to other contexts as well, so you could actually share that method across different components.
EDIT: There are many different ways to bind the context of a function, you are not limited to Function.prototype.bind. See this chapter for an explanation of the various ways to do so.
Right ahead I can say that Yes you can pull out different methods from other classes or files other than created in your component. There lots of different ways to go and it really depends on your preference. You can go from really simple to really complex structures.
First thing you need to search and learn about (if you don't already know) require() and/or ES6 import and export. You can create stand alone functions or objects and import them into your component to use them. If you have repeating functions that you use in different components or parts of your app this is the way to go.
If I comment on passing this as a parameter, it is not pretty like you said in your question. Rather than passing this, passing required parameters to functions and using callbacks or Promises is the way to go. Another technique you can use is to bind function to this. ES6 arrow functions don't need to be bind since they don't bind their own this.
If you would like to go a little more complex/complicated you can always create your own classes. Class structure can give ability to do more complex things. extends gives you ability to extend (like you can understand from its name) your class methods with others or overwrite them with new ones. For example, Beverages, Snacks, Meats can be classes that extends from Foods class. When you create a custom component you extend a React.Component and then you use its methods.
Another thing to consider is that having a 2000 lines component makes me think that you should also consider separating your components into smaller chunks. Parent/Child component relationship is most common and supported structure in React. If you use this pattern your code will automatically get smaller and it will be much more easier to follow and manage. There are lots of examples on how to pass functions as props to child components and run them in certain conditions with certain parameters and then manipulating parent component's state. You can look for those examples to get better understanding.
I hope these topics will help you to understand couple of thing and show you to where to start.
Webpack is a fully-featured javascript app bundler.
With Webpack you can import / export code like:
export default class CustomerView {
render() {
...
}
}
and
import CustomerView from './CustomerView'
`

Categories

Resources