is there such a thing as JSX 'partials'? - javascript

I work mainly with Handlebars JS now, but I am looking at JSX. Is there a JSX equivalent to Handlebars partials? I want to know if I can create small bits of markup that I can reuse in several different JSX views.

It doesn't provide partials. Some things about React:
React doesn't provide any notion of partials. The fundamental, atomic unit of React is the component.
Instead of passing a partial, you'd create a component or components and re-use those. Even better than a partial because it's a function, so it's encapsulated and testable!
If the markup is small, it should probably either be moved up into a parent component or down into a simpler one
Generally, my rule of thumb is that components should follow the principle of single responsibility or separation of concerns. If something doesn't seem to fit into a component, you've likely got problems in the other two components and could reconsider them, too :)
Another couple rules of thumb to go by when thinking about components:
code smells should usually end up as components (repeating something over and over again, etc.)
components are usually either presentational or containerized. The latter have roles in the props/state tree for an app (you never "see them")
refactor things into components as you need to; don't start out encapsulating everything, because you may have prematurely refactored and created more problems for yourself
the most reusable and decoupled components are like the best functions or objects: clean, flexible, testable, and they do address a single concern
at the same time, don't go crazy and turn everything into a component. i.e. you don't (usually) want:
<Letter>R</Letter><Letter>e</Letter><Letter>a</Letter><Letter>c</Letter><Letter>t</Letter>
Here's an incredibly simple example:
'use strict';
const OuterComponent = React.createClass({
render() {
return (
<div>Outer{this.props.children}</div>
);
}
});
const ReusableComponent = React.createClass({
render() {
return (
<div>Am I reusable? {this.props.reusable && 'Yeah!' }</div>
);
}
});
ReactDOM.render(
<OuterComponent>
<ReusableComponent reusable={true}/>
</OuterComponent>,
document.getElementById('container')
);
Will render:
OuterComponent
Am I reusable? Yeah!
Note, though, that using creatClass provides you more than you might need if you're not working with mutable state (which is provided to you within the component via this.state), you can easily use what are sometimes called "stateless functional components" (because they are, well, stateless and returned by functions). These could easily be arrow functions implicitly returning the JSX (which is essentially just React.createElement() generator)
const OuterComponent = (props) => <div>Outer{this.props.children}</div>;
const ReusableComponent = (props) => <div>Am I reusable? {this.props.reusable && 'Yeah!' }</div>;
ReactDOM.render(
<OuterComponent>
<ReusableComponent reusable={true}/>
</OuterComponent>,
document.getElementById('container')
);

Just create a component for that. Components can be as simple or as complex as you want them to be.
Example:
function Badge(props) {
return <span className="badge">{props.counter}</span>
}
With a corresponding .badge CSS class, this could be a very simply component that renders as a red circle with a number, and is used as <Badge counter={42} />.

Related

React: jsx in a variable vs a function vs a separate component

For rendering smaller components/jsx within a bigger component, there are multiple approaches that one can follow. For example, consider this:
Method 1:
function BigComponent(props) {
const renderSmallComponent1 = () => <div>{props.a}</div>;
const renderSmallComponent2 = () => <div>{props.b}</div>;
return (
<div>
{renderSmallComponent1()}
{renderSmallComponent2()}
</div>
)
}
Method 2:
function BigComponent(props) {
const smallComponent1 = <div>{props.a}</div>;
const smallComponent2 = <div>{props.b}</div>;
return (
<div>
{smallComponent1}
{smallComponent2}
</div>
)
}
Method 3:
function SmallComponent1({ a }) {
return <div>{a}</div>;
}
function SmallComponent2({ b }) {
return <div>{b}</div>;
}
function BigComponent(props) {
return (
<div>
<SmallComponent1 a={props.a} />
<SmallComponent2 b={props.b} />
</div>
)
}
I am just trying to understand the difference in these 3 in terms of
dev experience,
how the framework treats them,
are there any performance optimizations,
are there differences in runtime behaviours in all of these?
Is either one better to use in certain scenarios?
These are the things that I understand:
in Method 3, all SmallComponent are React components which are rendered in another component, so they would have a component lifecycle, while in method 1 and 2, they are simple jsx, which does not have lifecycle, so they would not be mounted / unmounted as React components
in Method 2, we would be eagerly evaluating the JSX as it is directly a variable, while in method 1, it would only be evaluated when the function is called in render. So, in case, we have any conditional rendering, the eager evaluation might just be wasteful.
A few other helpful articles:
https://medium.com/missive-app/45-faster-react-functional-components-now-3509a668e69f
https://kentcdodds.com/blog/dont-call-a-react-function-component
UPDATE: it seems observation 1 is incorrect as all 3 of them would still be rendered as react components, and hence would have a component lifecycle. So react would mount/unmount them.
UPDATE 2: No, observation 1 is correct, method 1 and 2 are both treated as regular jsx as part of the BigComponent and they are not treated as react component which have a lifecycle.
UPDATE 3:
There is another method Method 4:
function BigComponent(props) {
const SmallComponent1 = () => {
return <div>{props.a}</div>;
}
const SmallComponent2 = () => {
return <div>{props.b}</div>;
}
return (
<div>
<SmallComponent1 />
<SmallComponent2 />
</div>
)
}
this is similar to Method 3, but Method 3 vs Method 4 is slightly different in execution, when debugging through dev tools.
Method 2:
function BigComponent(props) {
const smallComponent1 = <div>{props.a}</div>;
const smallComponent2 = <div>{props.b}</div>;
return (
<div>
{smallComponent1}
{smallComponent2}
</div>
)
}
If you want to a large UI into seperate smaller UI, this method will give you best performance because
It is still just one big UI component.
react just have to solve variable references.
while re-rendering, BigComponent,smallComponent1 and smallComponent2 are rendered together as single unit.
smallComponent1 and smallComponent2 cannot have their own state, life cycles and hooks.
smallComponent1 and 2 needs to be re-initialized everytime Bigcomponent state is changed. So it is good practise to wrap them with useMemo() if the result of those smallComponents are coming from an expensive computation.
Method 3:
function SmallComponent1({ a }) {
return <div>{a}</div>;
}
function SmallComponent2({ b }) {
return <div>{b}</div>;
}
function BigComponent(props) {
return (
<div>
<SmallComponent1 a={props.a} />
<SmallComponent2 b={props.b} />
</div>
)
}
React needs to resolve reference as well as execute the function after resolving the reference.
It is a composition of react's actual child components into a large Component.
Child components are allowed to have their own hooks.
Child components are not re-initialized but are re-rendered if BigComponent state is changed.
There is chance of SmallComponent1 and SmallComponent2 getting re-rendered multiple times on BigComponents rendering once if small components are updating thier own state based on props change in parents.
if each SmallComponents are supposed to use multiple props which state of BigComponents, Keeping SmallComponents outside BigComponent does offer good developer experience.
I hope Method 1 and Method 4 can also be understood using these above points.
Note: childcomponents stored in variable and childcompoents as function becomes tricker if your application logic is using ref or DOM element for maininting focus or anchor point of rendering.
Have you taken a look at the compiled JS in a React project?
JSX tags are essentially transformed in to React.createElement statements. You can read the docs here. Essentially the syntax is:
React.createElement(FunctionOrClassComponent, { props }, ...children)
In all three of your examples this would take place. In all three examples, the smaller components are functional components rather than class components. That is to say, they don't have the React lifecycle methods of a class component, but they can use equivalent React hooks - should you want to.
Edited: Evaluation (instantiation and rendering) depends on your render logic. If you have conditional rendering statements or your functions return null (or less content) based on certain conditions, then obviously you're doing less work. And as you rightly pointed out in the comments below, when you assign a JSX.Element to a variable, that is evaluated inline rather than as a result of a function - so that happens immediately.
To me, all three are valid approaches. To address your questions:
dev experience,
for small components with minimal state, functional components as variables or lambdas are convenient to write and easily read/parsed when revisiting code at a later date. When a component becomes more complex, you may have to reconsider how it's written and perhaps use Class components.
how the framework treats them,
to my knowledge the framework treats all three of your examples the same in terms of compilation. I'm unsure about rendering optimisation.
are there any performance optimizations,
your examples don't depict anything computationally onerous so performance optimization options are not so obvious
are there differences in runtime behaviours in all of these?
they are all translated to React elements, monitored for props changes, and re-rendered if parents re-render (if things like React.memo are not employed) -- there may be differences vs class-based elements, but I would guess that the runtime differences between your three examples are minimal
Is either one better to use in certain scenarios?
The differences between all three are more a matter of standards or etiquette than functional outcome. As a developer, I would be able to read and understand all three, but working in a team - I would want to see a standard approach.

Is the reason props in React shouldn't be changed/mutated is because React wants elements to be as predictable as possible?

From React documentation.
Conceptually, components are like JavaScript functions. They accept
arbitrary inputs (called “props”) and return React elements describing
what should appear on the screen.
Considering:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
or
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Will give us the ability to do this:
<Welcome name="Luke" />;
<Welcome name="Leia" />;
to use as we wish in the DOM,
Hello, Luke
Hello, Leia
Now when people prescribe props shouldn't be changed, it would make sense the reason is in my thinking would be like the same as changing the values of attributes of an image tag?
HTML:
<img id="Executor" alt="Picture of Executor" src="/somepath/vaders-star-destroyer-executor.jpg"/>
JS:
Meanwhile in a Javascript file a long time ago in a galaxy far, far away...
var imageOfVadersStarDestroyer = document.getElementById('Executor');
imageOfVadersStarDestroyer.src = "/somepath/vaders-star-destroyer-avenger.jpg"
Because if we keeping changing an elements attribute values this can cause confusion and slower renderings?
So is the reason why the prescription is to never change props in React is because is the library is trying to make elements as predictable as possible?
Setting props outside of React is dangerous and should be avoided. Why? The main reason is that it doesn't trigger re-renders. Hence bugs and unexpected behaviour.
Re-rendering
Most of the time, props are data that is store as state in the parent component, which is manipulated by calling setState() (or the second function returned by React.useState()). Once setState() is called, React re-renders and computes what has changed under the hood, with the latest props and state. Manually assigning values to props, therefore won't notify React that the data has changed and something has to be re-rendered.
The good practice
Making props read-only allows React components to be as pure as possible, which is obviously a good practice anyway even when writing plain JS. Data won't be changed unexpectedly and can only be done so by calling setState() (You might have heard of the single source of truth, which is what React is trying to leverage).
Imagine you notice something went wrong in the app and the data shown to the end user is completely different from the source, it would be a pain trying to find out where the data has been manipulated wouldn't it? :)
never change props in React
means that you should never do this.props.name = "userName" because of React's one way data binding, props are read only, to update a component's props, you should pass a function from the parent that will do that ( in the parent ) , or dispatch an action if you're using redux, a change in the props will trigger a re-render
props is a constant in this case. You will always need it in your components.
But there is a cleaner way to write it or even omit it.
Regular way with Function Expression (same as your exemple)
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
ES6 Object Destructing - explicit
function Welcome(props) {
const {name} = pros
return <h1>Hello, {name}</h1>;
}
ES6 Object Destructing - inplicit, cleaner way
function Welcome({name}) {
return <h1>Hello, {name}</h1>;
}
And of course, you can use the class way which requires the usage of this.props.yourAttr
However, in the new version 3 of create-react-app, changed class components to functional components. You can see this exact modification on Github here.
You can need to learn more about destructing assignment in the old and good MDN linked here or an in-depth approach both array and object destructuring here.

Why use stateless functional Components instead of class-based Components?

I am learning ReactJS and I've learned that there are UI Components and Container Components. The Container Components are implemented using classes extending React.Component and contain state and good old render method, whereas the UI Components are created using functions and they are concerned with UI only as they only take the data from props.
Sample stateless functional components:
const Ninjas = (props) => {
const { ninjas } = props;
const ninjalist = ninjas.map((x) => {
var divStyle = {
color: getRandomColor(),
};
return (
<div className="ninja" key={x.key} style={divStyle}>
<p>Name: {x.name}</p>
<p>Age: {x.age}</p>
<p>Belt: {x.belt}</p>
</div>
);
});
return <div className="ninja-list">{ninjalist}</div>;
};
export default Ninjas;
The same sample as a Container Component
export default class Ninjas extends Component {
getRandomColor = () => {
....
return color;
};
render() {
const { ninjas } = this.props;
const ninjalist = ninjas.map((x) => {
var divStyle = {
color: this.getRandomColor(),
};
return (
<div className="ninja" key={x.key} style={divStyle}>
<p>Name: {x.name}</p>
<p>Age: {x.age}</p>
<p>Belt: {x.belt}</p>
</div>
);
});
return <div className="ninja-list">{ninjalist}</div>;
}
}
So my question is why do we even bother to make a UI component (not using the render method which is used in Container Component) when we could have easily done the same thing as a Container Component.
Functional state-less components (what wrongly you refer as UI Components, all components are UI components both statefull and stateless) are simply a short-hand method to create components that simply render something based on props passed and do not need to keep internal state.
Of course one can always use class-based components which extend React.Component. But why not have a short-hand to save time and space and simplify things if we can. There is nothing forcing you to create functional components, you can always use class-based components, only if you need to simplify and save time and space.
According to Functional vs Class-Components in React article:
So why should I use functional components at all?
You might ask yourself why you should use functional components at
all, if they remove so many nice features. But there are some benefits
you get by using functional components in React:
Functional component are much easier to read and test because they are plain JavaScript functions without state or lifecycle-hooks
You end up with less code
They help you to use best practices. It will get easier to separate container and presentational components because you need to think more
about your component’s state if you don’t have access to setState() in
your component
The React team mentioned that there may be a performance boost for functional component in future React versions
I would add a 5th point that React references (with React 16.3+) which provide functionality to access the DOM nodes directly cannot be used with Functional Components.
In React v.16.8+ useState hooks are introduced which enable functional components to be state-full while still being functional.
Furthermore with the introduction of React.memo higher-order component we can use memoization to avoid re-rendering of a functional component given that it renders same stuff for same props (shallow tested for difference)

What's the difference between using a stateless functional component versus calling a method?

I'm trying to understand stateless components and what the difference is between these examples:
class App {
render() {
return (
<div>
{this.renderAFunction('hello')}
</div>
);
}
renderAFunction(text) {
return (
<p>{text}</p>
);
}
}
and this:
class App {
render() {
return(
<div>
<RenderAFunction text='hello'/>
</div>
);
}
}
const RenderAFunction = ({text}) => (
<p>{text}</p>
);
Or if there is any difference at all?
Functionally, there is absolutely no difference. Both end up rendering a paragraph element, but there are other aspects to consider. There are three points to make (in my opinion) when examining both methods:
Reusability: You have to understand to separate components when you need to. If renderAFunction is just meant to generate some JSX based on, for example, an API request, then it's fine being in a method. But if you want to reuse it somewhere else, then separate it into it's own component. A huge part of React is component reusability and getting rid of code duplication. Separating the method into it's own component would be imperative to accomplish this.
Purpose: There are reason to use stateless function components and reasons not to. The whole point of stateless functional components is to not have state and be presentational. If you need to do something that involves the React lifecycle or internal state, keep it as a method, or new class depending on if you want it reusable.
Performance: Using a stateless functional component would be less efficient. This is because it's a component, not just some JSX returned from a method. As of right now, the React team plans on making some optimizations for stateless functional components because they do not contain state and are merely presentational, but this probably won't happen until after React Fiber is done and thus your stateless functional component has no optimizations versus a regular full-fledged class component. That makes it incredibly inefficient versus a method returning some JSX, especially if it's just used once in another component.
A good rule of thumb is to ask yourself, do I need it anywhere else? If not, then keep it in a method. If you don't need it anywhere else, separating the JSX into a separate component would have worse performance and wouldn't follow React's core principles.
If you are going to need it somewhere else, then separate the component so you follow React's concept of reusability.
Your App's render function will be translated into following JS code for your first example:
render() {
return React.createElement(
'div',
null,
this.renderAFunction('hello')
);
}
And the following one for the second one:
render() {
return React.createElement(
'div',
null,
React.createElement(RenderAFunction, { text: 'hello' })
);
}
While they both looks almost the same, there is one significant difference: laziness. React will execute RenderAFunction body only in case it gonna be mounted to the DOM hierarchy.
It is insignificant is your case, but imaging following example:
const LazyApp = () => {
const heavy = <div><HeavyStuff /></div>
// ...
return <div>done it</div>
}
const HardWorkingApp = () => {
const heavy = <div>{HeavyStuff()}</div>
// ...
return <div>done it</div>
}
const HeavyStuff = () => {
// ... do heavy rendering here
}
Lazy app will not perform any heavy stuff at all. Maybe it is not very clear from that synthetic example why one would do anything like that at all. But there are real-world examples out there, when something conceptually similar (creating Components without rendering them) is happening.
Basically, both will serve the same purpose. But the real advantage of creating a component is its reusability.
If you have to render that particular piece of jsx just for this component. Then, there is no need to create a separate component.

React.js: Is it possible to namespace child components while still using JSX to refer to them?

So let's say I have a component called ImageGrid and it is defined as below:
window.ImageGrid = React.createClass({
render: function() {
return (
<div className="image-grid">
<ImageGridItem />
</div>
);
}
});
As you can see it includes a child react component called ImageGridItem. Which is defined below.
window.ImageGridItem = React.createClass({
render: function() {
return (
<div className="item-container">something</div>
);
}
});
This works fine as long as both are directly properties of window. But this is kind of horrible so I'd like to group up all my react components under a namespace of window.myComponents for example.
So the definitions change to:
window.myComponents.ImageGrid = React.createClass({...});
window.myComponents.ImageGridItem = React.createClass({...});
The problem now is that as ImageGrid refers to <ImageGridItem /> in it's render() function, the JS version of this gets compiled out to JS as ImageGridItem() which of course is undefined since it's now actually myComponents.ImageGridItem() and react complains it can't find it.
Yes I realise I can just not write JSX for that component include and manually do myComponents.ImageGridItem({attr: 'val'}) but I'd really prefer to use the JSX html syntax shortcut as it's much easier to read and develop with.
Are there any ways to get this to work while still using the <ImageGridItem /> syntax for children? And if not is it possible to define the JS namespace within the JSX?
This pull request was just merged:
https://github.com/facebook/react/pull/760
It allows you to write things like <myComponents.ImageGridItem /> in React 0.11 and newer.
That said, a proper module system is the recommended way to manage dependencies to avoid pulling in code that you don't need.
Currently, there isn't a way to do this. Namespacing with JSX is on the todo list.
Most people use some kind of module system (browserify, webpack, requirejs), which replace namespacing and allow components to be used easily. There are a lot of other benefits, so I very much recommend looking into it.

Categories