Function declaration in React Components matters? - reactjs

Here is my question: What is the difference between these two declarations:
Whats the matter if I declare it on top of my component and what if within it?
Thank you in advance.

Functions that are created inside class components are usually referred to as methods.
If your function doesn't depend on class instance properties state or props and is independent of the component you can define that function outside the class.
But if your function need access to the class state, prop or any other class methods, you'll need to define it within the class component so you can use this.state or this.props.
So, thumb rule would be that if you need any access of the class component instance i.e. this within your function, you will need to define the function inside the component.

Related

Keeping Class Component methods pure by instead passing props or state as arguments

It's typical to access props/state from within Class Component methods as in bar() however, it's much nicer to unit test a more pure equivalent as in foo() as you don't have to repeatedly mock external state.
foo(state, props) {
// do something with state or props passed as argument
}
bar() {
// do something with this.state or this.props directly
}
However something about having state/props available throughout a Class, but passing state/props as arguments in all methods which could be pure feels antithetical to the Component state/props typical usage patterns.
Is this the typical way of refactoring Class Component methods for easier unit testing, or am I missing some React functionality which does this behind the scenes?
It depends what you want to test. For example if you'd test your components the way a user would interact with them, you'd write your assertions in a way that test if the rendered output is correct and if it correctly changes based on various interactions with it (button click, etc). In that case you wouldn't need to concern yourself with such implementation details as which props/state a component has at a certain point of time.

Missing constructor body inside Class

I am reading type definition of react in here. Inside the code, I found inside class Component {} (in line 396), there is constructor without body as below (line 435 ):
constructor(props: Readonly<P>);
Why there is no implementation of constructor inside a class. Can someone explain?
you are reading index.d.ts
its only typescript definition for javascript implementation.
read more here
Since React is what instantiates the class for you, the type definition is simply informing you of what would be passed to the constructor if you decided to provide one.
This is also useful because it instructs you how to call super(). If you were to create a constructor, you would need to pass the received props to super even if your class did not need them, e.g.
constructor(props) {
super(props);
// your constructor logic here
}

How should I handle component state following single responsibility pattern

I'm new to ReactJs and trying to follow best practices. From my research, I've come across a couple of contradicting articles discussing how implementation should be.
Should state rely on the properties being passed down from a parent component? In the comparisons below, they are both following SRP, but not sure which is best. Would like your advice, Thanks!
1. -- Best Practices for Component State in React.js
First, and probably the most important of all, the state of a component should not depend on the props passed in. (see below for example of what we should not do)
class UserWidget extends React.Component {
// ...
// BAD: set this.state.fullName with values received through props
constructor (props) {
this.state = {
fullName: `${props.firstName} ${props.lastName}`
};
}
// ...
}
2. -- 7 architectural attributes of a reliable React component
Let's refactor to have one responsibility: render form fields and attach event handlers. It shouldn't know how to use storage directly.....The component receives the stored input value from a prop initialValue, and saves the input value using a prop function saveValue(newValue). These props are provided by withPersistence() HOC using props proxy technique.
class PersistentForm extends Component {
constructor(props) {
super(props);
this.state = { inputValue: props.initialValue };
}
// ...
}
3. -- In my case, I have something like the following (wondering if this is an acceptable implementation?) - Should state be handled in Tasks, or in another TasksWithPersistence type of component that sits between TasksWithData and Tasks?
export default function TasksWithData(TasksComponent) {
return class withData extends React.Component {
render() {
const tasks = TaskAPI.getTasks();
return (
<TasksComponent
tasks={tasks}
{...this.props}
/>
)
}
}
}
export default class Tasks extends React.Component {
state = {
tasks: [],
addItemInput: null
};
// ...
componentDidMount() {
this.updateComponentState({tasks: this.props.tasks});
}
componentDidUpdate() {
this.prepUIForNextAddition();
}
// ...
}
The gist of your question seems to revolve around the anti-pattern that is to take some props and duplicate it into the state. This, mutating of props, isn't the purpose of the state. Props are immutable, duping them to the state defeats this design.
The purpose of the state is to manage things that are specific to the React Component, i.e. tightly scoped to only that React component. For instance a showHide switch for something to display within the React component. Think of the state as a locally scoped variable if it helps.
Most of the time this anti-pattern of duping the props can be satisfied by a function within the React object. For example, your state.full_name variable becomes a named function, fullName, bound to the React Component. (all code examples are assuming JSX syntax)
Note: in JavaScript camelcase is the naming structure for functions and variables, I'm assuming you're coming from ruby based on the underscore naming convention. IMO it's best to stick to the convention of the language with which you're writing the code. This is why I use camelcased naming.
...
fullName() {
return this.props.firstName + " " + this.props.lastName
}
...
That function can then be called within the render of the component
# in render() portion of your React component, assuming jsx syntax
<p>Hello, {this.fullName()}</p>
Note: Remember that in ES6 you have to bind the methods in your react class in the constructor or use => syntax so that you can call them with this.
...
constructor(props) {
super(props);
this.fullName = this.fullName.bind(this);
}
...
You could also decompose the relevant parts to a new Component called FullName if it will be utilized by multiple components.
<FullName firstName={this.props.firstName} lastName={this.props.lastName} />
Technically, "the react way" is, at least in this author's opinion, to decompose this into another component for reusability. However component reuse needs to be weighed against the complexity added, i.e. don't optimize prematurely. So you may not want to take that too far at first. The times when it's necessary will emerge naturally.
A very broad generalization of React's props is that they are guaranteed, are immutable, and they flow down like a waterfall from the topmost component. If you need to update them, update them at the highest level where it makes sense.
In a soley React based approach, if you have something that a parent needs to be aware of, "lift" that part of the code up to the parent and vice versa bind it down to the child as a props, e.g. an AJAX function that calls an API. I think of it as trying to keep the components as dumb as possible.
The parent becomes the "source of truth" for the item you "lifted". The parent handles the updates, and then passes the results to the children. So in the parent, it may exist as a state variable and then get passed as props to the child object, which then passes it along as props to it's child object, etc. The children would update as the state gets changed in their parent when it propagates down through the chain as props.
If your app is React only, i.e. no stores that manage objects such as in the flux pattern or redux pattern, you may have to store things in the topmost objet's state which technically could be viewed as bad. As your system becomes more complex, this functionality would be better handled by flux or redux's parts.
Hope this helps!
There is a huge difference between example 1 & 2.
In example #1, the reason it's bad to set state from the those props in that way is that if the props change, the widget will not update. Best practices or not, that is just wrong and bad in any framework. In that particular case, there really is no point in even using the state. Props alone will suffice.
In example #2 the prop is only being used to give the state an initial value (The prop is even named initialValue), implying that further changes to the state will be controlled by the component regardless of prop changes. It does not break single responsibility principle to use props for an initial state, especially when it's explicitly use for that purpose.
I really don't see those two examples as being contradictory because they are completely different. Further, there is no rule in single responsibility principle that you can't set state from props, you just need to pay attention to the context in which you are doing it.

What is the difference between using a method or a function outside React component

Recently i found a React component that uses a function outside the component in a onClick attribute. The reasoning behind that is that, and i quote: "it is better to use a function outsite the React component when there is not need to use this context". I personally don't find that answer very satisfying.
You can find a codesanbox example here
There's any real difference? maybe in performance?
Thanks!
You must effectively write function outside of component if you don't need "this" context. The benefits is that the outside function is instantiated only one time and shared by all the component instances.

What, formally speaking, is a react component?

Consider
var MyComponent = React.createClass({
render: function() {
//...
}
});
as well as
var element = React.createElement(MyComponent);
Which specifically, or where specifically, is the "component"? Is it the object returned by the call to React.createClass(..)? Is it the object returned by React.createElement(..)? Is it behind the scenes somewhere in between?
There's a post on the React blog that answers your question.
http://facebook.github.io/react/blog/2015/12/18/react-components-elements-and-instances.html
Basically, components are your class definitions, elements are created from your components in render(), and instances are your component's representation in the DOM.
Obviously http://facebook.github.io/react/ is the authority here - a component is conceptual construct that has properties, state, and a render function. Although the first two are optional. Components are typed using a "class" (ES5 prototypes, ES6 classes, etc), which React is formally made aware of using the createClass function. Component instances are elements in a larger whole, loaded into a UI context (the browser, a phone, whatever), usually called an app, and created with createElement.
This post answers the question in great detail.
In short: components are -- literally speaking -- functions that take an object with a props field and, in turn, return a React.Element. Components can be pure functions, or JS classes (which are functions with syntactic sugar over them anyway). You can define a component via React.createClass; the output of React.createClass is -- as I understand it -- still literally a component (although several instances of it can be instantiated behind the scenes via React, each of which can be accesssed via this within the class definition; these instances are also components).
Finally, React.Element is nothing but a "description" of a component instance or a dom node. Literally, it is a javascript object with fields like props and children (it also has a field type, which is described in the article). Crucially, an instance of a React.Element is NOT a component; it merely describes one. Moreover, the output of a React.createClass() is a component, as well as any function that takes an object with a prop field and returns an instance of a React.Element.

Resources