React should form elements be a separate component? - javascript

I keep reading that when in doubt I should turn an element into a component. So are there actually any benefits to turning form elements such as <input /> to components.
Consider the following:
const SomeComp = (props) => {
return (
<form className='someClass' onSubmit={props.handleSubmit}>
<Input
className='someClass'
type='text'
id='someId'
placeholder='Enter Something'
onChange={props.handleChange}
value={props.side}
/>
</form>
)
}
Unless I'm using options like autoCorrect, autoCapitalize, spellCheck the only things I'll save by wrapping the input into a component like <TextInput/> and importing it to various forms is not adding the type prop to each input and maybe the fact that the error for the input is not declared at the top of the form.
Is there anything else I'm missing? What's the most beneficial way to approch such form elements and why?

Usually you will not want to turn very simple elements like inputs into separate components, unless you are expecting some special functionality from them.
The simplest way to go through is to always have, for each functional need (like a login page for example), a smart component for handling the behavior and functionality, and one dumb components for displaying the ui elements.
When you start feeling there is too much code in some of your smart components, or a dumb component has gone to large you can start dividing them. Otherwise try to keep it simple.

I use styled-components and do stuff like this all the time. The basic idea with Styled Components is that you attached CSS styles to your component instead of creating CSS classes to target, for example, all input elements or using inline styles which limit what you can do (i.e. media queries, psuedo-selectors, etc). And it allows you to separate your components functionality from it's presentation (within the same file).
Here is a link to a youtube video on the topic: https://www.youtube.com/watch?v=jaqDA7Btm3c
This way, you avoid the need for a global CSS file that is hard to maintain and doesn't exactly fit well within the webpack ecosystem that views your assets as a graph of dependencies.
If you are not interested in styled-components, and are happy with the way you style your form elements, then I see no reason to create a custom Input component.
For example, in Facebook's docs on React forms, they do not create custom form components.
https://facebook.github.io/react/docs/forms.html
Unrelated:
If you don't already know, you can write your example like so:
const SomeComp = props =>
<form className='someClass' onSubmit={props.handleSubmit}>
<Input
className='someClass'
type='text'
id='someId'
placeholder='Enter Something'
onChange={props.handleChange}
value={props.side}
/>
</form>
(removed the () around the single argument, and removed the {} and return statement. Like I said, unrelated, but thought I would mention it in case you were not aware.

Related

Angular component creation best practices

I'm often in doubt when I want a new behaviour of a component.
Let's make a simple example, I have <app-title> component:
<div>
<h1>{{title}}</h1>
</div>
Some time after, inside another page I need to put a button alongside the title. The problem is, should I create a new title component or should I parametrize the existing one?
I can edit <app-title> to look like this:
export class AppTitleComponent implements OnInit {
#Input() showButton: boolean;
title = 'App title';
constructor() {}
ngOnInit() {}
}
<div>
<h1>{{title}}</h1>
<button *ngIf="showButton">{{buttonTitle}}</button>
</div>
This is a simple example and may be obvious but using Angular I always have this problem, think about complex components: the #Input() would become many using this method, but creating a new component would increase files and complexity.
From this example you could say to create two components, one for title and another for button but that's only because this is a very simple case. Think about changing a component from "compact" mode to "expanded" and viceversa. On the one hand you may need to have the large component and on the other hand have it smaller in size and showing less information
Is there some guideline about this?
Thanks
I think it's important thinking about behavior within the context of your component. Is the button core to behavior of the title component? Does it make sense to not only display the button, but also handle its events within the context of the title component? If the answer is no, then at some granular level I'd split the components.
Here are some other things you can consider:
Anticipating that your title component may need some content wrapped with the title, you can use transclusion:
<div>
<h1>{{title}}</h1>
<ng-content></ng-content>
</div>
Then, in the parent, you'd do something like this:
<div>
<app-title-component title='title'>
<button>Some Button Text</button>
</app-title-component>
</div>
You could write a wrapper component that packages the title and the button together... ie:
<div>
<app-title-component></app-title-component>
<button>Some Button Text</button>
</div>
You could, as suggested, parameterize the configuration. I recommend thinking about if the behavior that you are parameterizing is part of the core behavior of the component. For example, if you want to paramaterize whether or not a legend shows on a chart, that makes sense because the legend is a core feature of the chart. But I probably wouldn't parameterize whether or not the chart should be followed by a raw data sheet. Instead I would create a new component for that and render them in sequence, because the data sheet is not part of the core behavior of the chart, even though sometimes I'd want to put them next to each other.
At the end of the day, you have to think about the decision in terms of your app, your app's future usability, and developer ease (e.g.- will it make sense to a future developer that this button is packaged with title).
I hope you find this helpful.

Modifying or adding classes to individual components within core wordpress blocks

I am having difficulty modifying or adding additional classes to individual components of wordpress blocks. I essentially just want to add a class or classes to some of the pieces that make up some of the core wordpress blocks to do things like add bootstrap styling.
An example of this would be the image gallery block. It works well enough for my purposes, but I may want to do something like add an "img-fluid" or "img-thumbnail" class to the images that are within that gallery.
I have looked through the documentation for block filters and I feel as though my answer is going to lie somewhere in there, I'm just not sure where yet.
I have tried using the blocks.getBlockDefaultClassName filter, but this adds a classname to the entire block as opposed to individual pieces that make up that block (such as the images in my gallery example).
This is the example they give for it in the documentation:
// Our filter function
function setBlockCustomClassName( className, blockName ) {
return blockName === 'core/code' ?
'my-plugin-code' :
className;
}
// Adding the filter
wp.hooks.addFilter(
'blocks.getBlockDefaultClassName',
'my-plugin/set-block-custom-class-name',
setBlockCustomClassName
);
I feel as though blocks.getSaveContent.extraProps might do what I need it to, but I am not sure how to use it in this way. The example they use looks like this:
function addBackgroundColorStyle( props ) {
return lodash.assign( props, { style: { backgroundColor: 'red' } } );
}
wp.hooks.addFilter(
'blocks.getSaveContent.extraProps',
'my-plugin/add-background-color-style',
addBackgroundColorStyle
);
But even if I were to add an extra property like a class name, I would think I would then need to modify the actual save and edit functions (I guess using more block filters) to then use that class name when it displays those pieces (in this case - the images), and I'm also not sure how to do that.
Any thoughts or suggestions about this would be appreciated.
There are two kind of changes one is structural change and the other one is styling change. In your scenario you need styling change but you are actually looking for structural change. You can write your own CSS that can handles your block styling on editor view and on front end.
These are the hooks that you need to enqueue your styles enqueue_block_editor_assets (enqueue your styles only on backend editor) and enqueue_block_assets (enqueue your styles on both backend and frontend).

Mixing React Components with HTML Blocks

Something that's always confused me is how many React examples show everything as components. But's let's say I only need to include some simple HTML alongside my components, like:
class Homepage extends Component {
render() {
return (
<Container>
<Hero />
<Features />
<div className="copyright">Copyright Some Company Name.</div>
</Container>
);
}
}
The div element will never be more than static text.
Should the <div> be moved into a pure component? Or is it ok to simplify the Homepage component by adding plain HTML this?
Sure it's ok. all in all it's HTML in the end. React components are set of html elements when you call the render function.
One rule of thumb i follow is: create a new component when you think a new responsibility is in order.
That div is a component just like any other, except it is a "primitive" one. There should be no problem mixing the primitive components from HTML with your own custom components.

Why use this.props.children?

There are other similar questions that have been "answered", but the answers aren't complete and they don't solve the real problem.
This is really a two-parter with a sub-question.
1. What are the general situations you would want to use this.props.children?
2. What are some specific situations with examples?
I have read the docs, please don't only quote the docs.
Motivation for this quesiton:
The reason I for this question is that at the time of this question, the docs give a very very general example of how to use it and the methods to use when doing this, but the example don't give us true context. It isn't usable IRL. The example could be literally reused all over an app without rhyme, reason, or regards to sanity. Is that really ok?
I have been told you will use this.props.children, "when you don't know what children will be passed." But technically you never really know what changes may come down the line that require more or different children. So this is pretty ambiguous.
Also I found an interesting article by Jake Trent: http://jaketrent.com/post/send-props-to-children-react/
The article shows how you can add/remove props being passed to these "unknown children" based on the type of the component, which is neat(and possibly a good idea when you build a third party component).
My big takeaway so far is that you are giving power over the children to the parent, when you specify this.props.children Is this a good reason or just a byproduct? (example: proptypes, actual typechecking ... ) but,
2a. What other things would/could/should you do here?
2b. What things should you not do?
Examples please!
I like to think of components that make use of props.children as general wrappers, like most other HTML elements.
Think about the fieldset element.
<form action="/post">
<input type="text" name="myValue" placeholder="Some Data" />
<input type="submit" value="Submit!" />
</form>
What a pretty form we have made! But I want it to look...different. I want it to kind of look more visually like a form. Like I want some borders around it, maybe a little label in the top to describe it...Ahh I'll wrap it in a fieldset!
<fieldset>
<legend>A Pretty Form</legend>
<form action="/post">
<input type="text" name="myValue" placeholder="Some Data" />
<input type="submit" value="Submit!" />
</form>
</fieldset>
Now it looks just how I want! Sprinkled in a little legend too, to make this example...legendary.
The point is though, fieldset provides a reusable component with certain attributes that can be used to group HTML content. It's child elements are absolutely irrelevant to it's functionality.
Could we use the same principle in React? Yes. And it can be much more powerful!
Let's say we want to have a special ReactFieldset component, based on an HTML fieldset, that has it's own functionality. I'm not going to code that all out, because who has the time? But imagine you made a ReactFieldset component with a bunch of it's own functionality: it can collapse, it can move, it can do all kinds of things! And it can also hold any kind of content.
Well, then all you need to do in it's render function is:
render() {
return <fieldset { ...superFunctionalityControllingProps }>
{ this.props.children }
</fieldset>
}
Tada! You now have a reusable component that has it's own functionality, and can hold any children.
So the point is: this.props.children can be used when the children aren't really that important at all! The emphasis can actually just be on the component itself, whereas the children are arbitrary components it just happens to house. They needn't even be functionality related at all.
This is used a lot in React Native. Many different components have their own functionality, but can house any children, because they are just "wrapper" building blocks.

underscore js - renumber template rendered element attributes

I've got an form with the ability to have an infinite number of user-added inputs.
As an example, imagine a job application with an "add references" section. There's a "+" button, as well as an "Remove" next to any already added reference.
Here's an example template
<script type="text/template" id="referenceTmpl">
<div>
<h2>Reference No. <%= index %></h2><a id="removeRef<%= index %>">Remove</a>
Name: <input type="text" name="references[<%= index %>].name" />
Email: <input type="text" name="references[<%= index %>].email" />
(...)
</div>
</script>
When any "reference" is removed, I'd like to renumber the others. As the form inputs may already contain unsaved data, I need to do so without fully re-rendering the template. I'd like to do this in a salable way (one that doesn't require too much extra code per input) as the solution may be used in a more complex application.
Feel free to assume I'm using jQuery if the solution could benefit from it.
Any ideas?
The best way to do this kind of thing without hacking into the code, is to use a model(list) for your so called "references".
You should try Backbone.js in combination with Underscore.js:
Backbone.js documentation
There is an TODO example application that does exactly what you want:
Application code-breakdown
Example application
It might take some time to set up, but when you are finished, you will get work done much quicker.

Categories