bindActionCreators, #connect in React-Redux and understanding the code - javascript

I was trying to comprehend this code on github
Here they programmer have used something like this
constructor(props) {
super(props);
this.actions = bindActionCreators(Actions, this.props.dispatch);
}
Question 1: Here, this.actions = bindActionCreators(Actions, this.props.dispatch); doesn't make sense to me
Also, This isn't primary question but from where I learned React-redux, we used to connect component like this
export default connect(mapStateToProps,
{fetchCoin,
updateCrypto,
CurrencyRate,
CurrencyState
})(cryptoTicker);
In the above code Snippet the programmer have done something like this
#connect(state => {
return {
score: state.game.get("score"),
result: state.game.get("result")
};
})
Question 2: ** Which again sort of looks alien to me (like I have few months of experience using js but this is the first time I am encountering **#) So can someone please explain me what is # in general in JS?
And lastly he have declared two functions which are being called onclick after return statement of class
_handleNewGame = () => {
this.actions.initGame();
}
/**
* Save the current game`s state.
*/
_handleSaveGame = () => {
this.actions.saveGame();
}
Now Since I am still relatively new to JS and react, I have two questions for this part
Question 3: Can we create a function inside a class after return and render? If yes then wouldn't it have been a good practise (in general) to create a function before render where all the other functions are declared?

For question #1 and #2, your '#connect' and 'connect(mapStateToProps, ...)(cryptoTicker)' syntax is equivalent. The # indicates to the parser that we're using a decorator for our function, the connect(...) function, and outputs the same class, in this case Game, but with added functionality. This is called a HoC (Higher Order Components) design pattern and you can read more about it here https://medium.com/#mappmechanic/react-utility-higher-order-components-as-decorators-tc39-stage-2-9e9f3a17688a
For question #3, you are correct, it is better practice to leave the render function for the last function in the component.

Related

How to pass the set[State] function to a non-descendent trigger component

Here is the diagram. ChildComponentB has a state - stateX. In ChildComponentA, once the event occurs, it will change the stateX in ChildComponentB.
If the ChildComponentA is the child component of ChildComponentB, then it's easy, just pass the setStateX as a prop to ChildComponentA. But in this case, it's not.
The real scenario is the following. I have a canvas component, there are some static Rectangles already there, once there are mouse move over the line of the Rectangles, I'd like to add the indicator lines to another child component of the canvas component.
Hence, the rectComponent is not the descendent of the distanceIndicatorsComponent. So I can't pass the setLines to RectComponent.
What's your approach to do that?
If I use useContext approach, will it work?
Thank you, #KonradLinkowski to provide your solution. Here is his code. However, useContext is still lifing the state up to ParentComponent.
import React, { useContext, createContext, useState } from "react";
const Context = createContext();
function ChildComponentA(props) {
const { setStateX } = useContext(Context);
return (
<div>
componentA button:{" "}
<button onClick={() => setStateX((i) => i + 1)}>add</button>
</div>
);
}
function ChildComponentB(props) {
const { stateX } = useContext(Context);
return <div> stateX is {stateX} </div>;
}
export default function ParentComponent(props) {
const [stateX, setStateX] = useState(0);
return (
<>
<Context.Provider value={{ stateX, setStateX }}>
<ChildComponentA> </ChildComponentA>
<ChildComponentB> </ChildComponentB>
</Context.Provider>
</>
);
}
Regarding the reusbility of the ComponentB i.e. distanceIndicatorsComponent in this scenario, it includes the JSX and the states plus the interface in which there are logic to change the states. The are all parts which should be reusable in the furture.
From OOP perspective, the lines (state) belongs to DistanceIndicatorsComponent, and the how to change the lines (Add Line in this case) should be also reusable logic which belongs to distanceIndicatorsComponent.
However, from React perspective, to lift the setLines (this is the interface triggered under some event) is not "good enough" from OOP perspective. To lift the state - lines and state management function - setLines up to CanvasComponent is a "not good enough" in terms of the encapsulation. Put a wrap component on top of ComponentB is the same thing, the setLines still can't be passed to FrameComponent unless FrameComponent is a child-component of the wrap component.
It's very common to see there is a very heavy component holding all the state and the events at the top. It makes me feel that's a bad smell of the code. The reusability of the component should be based on a set of components, in this set of components, there is one uncontrolled component at the top, and underneath of this uncontrolled component are controlled components. This set of components is a external reusability unit.
Here, in this diagram, there should be more than one reusable unit rather than one. If lift the state up to CanvasComponent, it makes all the components underneath are un-reusable. In some extents, you still can re-use the JSX of this component, but I'd say, in terms of reusablity, it should invovle as many reusable logic as possible.
I might be wrong, please correct me. And thank you for sharing your valuable comments.
Requirements
First let us sum up the requirements.
Rect Component and Distance Indicators have not much to do with each other. Making them aware of each other or creating a dependency between them would be not desired in a good OOP design.
The interaction between both is very specific. Establishing a mechanism or a data structure just for this special sort of interaction would add an overhead to all components that don't need this sort of interaction.
General Concepts
So you must use a mechanism that is so generic that it does not add any sort of coupling. You need to establish something between these two components, which only these two components know and which for all the rest of your program is nonsense. What mechanisms serve for such a purpose?
Function pointers
Lambda functions
Events
Function pointers and lambda functions are complicated constructs. Not everybody prefers to use them. Now you see why events are so popular. They address a common requirement of connecting two components without revealing any of the details of them to anybody.
I personally recommend you to use lambda functions in this situation. Because this is one strength of JavaScript. Search in google for callback or asynchronous lambda function. This often adds the least overhead to existing code. Because a lambda functions has an important property:
With lambda functions you can do things very locally. Doing things locally is an important design principle. You don't need to define extra methods or functions or classes. You can just create them wherever you are, return them, pass them freely around to where you actually need them and store them there. You can store them even without knowing what is behind them.
I think, this is your answer. The only thing you need is a mechanism to pass lambda functions and to store your lambda functions. But this is on a very generic level and therefore adds no coupling.
With events you are on similar path. The event mechanism is already there. But therefore you already have a good answer.
Example with pure JavaScript
When applying this to JavaScript we can imagine that function pointers could be compared to function expressions in JavaScript. And lambda functions can be compared to arrow functions in JavaScript. (Note: Arrow functions also provide "closures", which is required in this case, see How do JavaScript closures work?).
A simple example illustrates this:
class DistanceIndicator {
constructor(height, width) {
this.height = height;
this.width = width;
}
resize(height){
this.height = height;
}
incorrect_resizer(height){
return this.resize;
}
resizer(){
return (height) => this.resize(height);
}
resizer_with_less_overhead(){
return (height) => this.height = height;
}
}
p = new DistanceIndicator();
p.resize(19);
// If you want to use this, you have to store p. You may see
// this as not so nice, because, you are not interested in what
// actually p is. And you don't want to expose the information
// that it has a method resize. You want to have the freedom
// of changing such details without the need of changing all
// the code where something happens with Rectangles.
console.log(p.height);
resizer = p.incorrect_resizer()
//resizer(18);
// In this example, resizer is a function pointer. It would be
// nice to store it and be able to call it whenever we want to
// inform Rectangle about something interesting. But it does not
// work because the resize method cannot be isolated from the
// class. The "this" is not there.
console.log(p.height);
resizer = p.resizer();
resizer(17);
// That works. Lambda functions do the job. They are able to
// include the "this" object.
console.log(p.height);
resizer = p.resizer_with_less_overhead();
resizer(16);
console.log(p.height);
// As you have now a resizer, you can store it wherever you want.
// You can call it without knowing what is behind it.
The idea in the example is that you can store the resizers wherever you want without knowing what they are. You shouldn't name them resizer, but give them a generic name like size_notification.
Example for React
The React concept for contexts is a typical candidate for data exchange between components. But the principle of React is a pure unidirectional data flow (top-down). This is also true for the context, which means, we cannot use a context for what we want.
React does not provide support for the implementation of the proposed idea. React is only responsible for the pure construction of the HTML page and a comfortable and performant rendering. It is not responsible for the "business" logic of our HTML page. This is done in full JavaScript. That makes sense because you want be able to develop complex web applications. Therefore you need all your favourite programming concepts. A real application does not follow the design principle of React. React is only a presentation layer. Most people like OOP progamming.
So when implementing something with React we must keep in mind that React is just a library for JavaScript. The full power of JavaScript is always available and should be used for our web application.
After realizing this, the problem becomes simple. See this code:
import React from 'react';
let sizeNotificator = (newValue) => {console.log(newValue)};
function Rect(props) {
return <button onClick={() => sizeNotificator("12")}>resize to 12</button>;
}
class DistanceIndicator extends React.Component {
state = {
size: "0",
};
setSize(newValue) {
this.setState({
size : newValue
});
};
componentDidMount(){
sizeNotificator = ((newValue) => {this.setSize(newValue);})
}
render() {
return <p>Current size: { this.state.size}</p>;
}
}
class App extends React.Component {
render() {
return(<div>
<DistanceIndicator/>
<Rect/>
</div>);
}
}
export default App;
With this code the requirement is fulfilled that none of the DistanceIndicator implementation details are revealed to the outside of DistanceIndicator.
Obviously this example code only works if there is not more than one DistanceIndicator. To solve this is a different topic with probably not only one good solution.
If keeping the shared state in the ParentComponent is the problem, you can extract the Context.Provider to a separate component and pass components as it's children, those children can access the context value via useContext hook.
function ParentContextProvider({ children }) {
const [stateX, setStateX] = useState(0);
return (
<Context.Provider value={{ stateX, setStateX }}>
{children}
</Context.Provider>
);
}
export default function ParentComponent(props) {
return (
<ParentContextProvider>
<ChildComponentA />
<ChildComponentB />
</ParentContextProvider>
);
}
Now you can add any new state/setState to the ParentContextProvider and can pass it to it's children
Have you looked at Redux stores? You could have a variable like "showLine" or "originX"/"originY", then have one child dispatch changes, and the other child useSelector for the values?
Do you know if Redux works for your use case?
I prefer to use a simple events pattern for this type of scenario. Eg using a component such as js-event-bus.
CHILD COMPONENT A
props.eventBus.emit('MouseOverRectangle', null, new MyEvent(23));
CHILD COMPONENT B
useEffect(() => {
startup();
return () => cleanup();
}, []);
function startup() {
props.eventBus.on('MouseOverRectangle', handleEvent);
}
function cleanup() {
props.eventBus.detach('MouseOverRectangle', handleEvent);
}
function handleEvent(e: MyEvent) {
// Update state of component B here
}
RESULTS
This tends to result in quite clean encapsulation and also simple code. Eg any React conponent can communicate with any other, without needing to reveal internal details.

Understanding JavaScript object properties (functions) referencing other properties in same object

So I have stumbled upon a React Hooks based component that uses objects to categorize various functions for readability.
For eg.
const MyComponent = (props) => {
const utilities = {
utility1: () => {
// ...some functionality
},
utility2: () => {
// ...some functionality
},
};
const renderers = {
renderer1: () => {
// ...some rendering logic
},
renderer2: () => {
// ...some rendering logic
return (
<span>{renderers.renderer1()}</span>
);
},
};
return (
// ...rendering logic
);
};
What I want to understand is why is renderer2 working correctly even when it calls renderer1?
What I understand is that the object will be declared when the code is executed and the declaration is not complete till all properties are defined (this is just my noob understanding, I may be entirely wrong).
I would be really interested in knowing why this little bit of code works, especially why does it work correctly?
Also, on a side note, compared to Class-based components, I feel Hooks-based components are not very readable, and this approach tries to mitigate the problem. So I was wondering if this is the best way to make a Hooks-based component readable, or if there are other better approaches for the same?
What I understand is that the object will be declared when the code is executed and the declaration is not complete till all properties are defined
This is not so. A variable declaration happens ahead of time - at compile time, before any code actually has had a chance to run. The assignement to a variable happens at runtime though. This includes evaluating the value being assigned.
So in the case you're talking about, when the object being assigned to renderers is being evaluated, the renderers variable is actually already declared.
Also, you have to consider the fact that renderers.renderer1() is not actually being called as part of the evaluation of this object - but only later on when renderers.renderer2() is actually be called, at which point both the object evaluation and the assignment will have completed, and thus renderers.renderer1() will be what you expect it to be.

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

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'
`

purpose of # operator in javascript/ [duplicate]

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

Categories

Resources