Reactjs inheritance - reactjs

I'm very new to React and I'm trying to make a simple application that renders html controls.
I want to have an API that return array of json objects contains properties that determine the type and the value of each control like id, type, value ... etc.
Let's say that I have some controls like Input and Button.
What I'm thinking of is Creating a base class named HtmlControl that extends React.Component and other html controls should extend from the HtmlControl and finally a class for rendering these controls.
How can I be able to render the controls that extends only HtmlControl class ?

That would not be a good choice as react says you should not focus inheritance rather focus on containment or composition.
React has a powerful composition model, and we recommend using composition instead of inheritance to reuse code between components.
and
At Facebook, we use React in thousands of components, and we haven't found any use cases where we would recommend creating component inheritance hierarchies.
Props and composition give you all the flexibility you need to customize a component's look and behavior in an explicit and safe way. Remember that components may accept arbitrary props, including primitive values, React elements, or functions.
Please Visit this link to learn more.
You can create separate classes for each of the components or elements and combine them in one class like this:
import Button from './Button'
import Radio from './Radio'
import TextInput from './TextInput'
class HtmlComponent{
// note: we don't need to extend it from React.Component
// we will some function to render them.
renderTextInput() { <TextInput /> }
renderRadio() { <Radio /> }
}
// you can now use below code:
const hC = new HtmlComponent();
hC.renderTextInput();
Note Again this is not a nice idea to do but you can achieve your goal.

Related

Reusable components structure (react native)

I want to seek advice regarding reusable components structure in react-native. I wanted to make them lean and adaptive. What I thought was to have generic components as wrappers and then have specific components using those wrappers. e.g. For products carousel I pass products data to Carousel component (just a FlatList) that renders Card component multiple times that has products details and product related icons. But what If I want to have categories or anything else inside card?
What I thought is to make card content passed as props
<Carousel>
{.... // ProductContent}
</Carousel>
<Carousel>
{.... // CategoriesContent}
</Carousel>
But it seems like I am over complicating things as I'll pass data to carousel, then carousel will pass it to card then card will pass it back to my content and carousel is mere a Flatlist and card is mere a TouchableOpacity. And also it will not look clean as I will have to define the content wherever I am using the Carousel. Why not just create two separate carousel components
<ProductCarousel />
<CategoriesCarousel />
Similarly I have a <PopUpModal /> component. which I am using for showing product details. Should I pass product content as children to keep content generic or just create <ProductDetailModal /> as a component and create more modals if required
So the point is whether to have specific bits and pieces of the app as components so that connecting them will complete the puzzle or to have generic customizable wrappers like components. Or something in between
I recommend atomic design.
Its hard to explain it here, so Ill leave a link.
https://bradfrost.com/blog/post/atomic-web-design/
The key point is to break(modularize) everything into tiny, replacable & reusable bits, and actually reusing and replacing them.
Another important, yet often neglected point is that separating smart and dumb components.
https://medium.com/#dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
This is surely neglected and also seems cumbersome to aplly, but will simplify the codebase by detaching view related logic to data(api) related logic.
So those are the two rules I try to stick to.
P.S. Just as im_baby has pointed out in the comments, there is no answer, and we all compromise at some point. So try to be long sighted and practical, dont be dogmastic to rules, neither be short sighted and mess up the overall code quality and structure for immediate comfort
You will make a component like this giving the parent component all the liberty to change it through props.
render() {
const { all the props that you want to give your component} = this.props;
return (
<Carousel>
{this.props.childern} // like this you can design your one carosal and cahnge the data/view in the carosal.
</Carousel>
);
}
Then in your parent component you need to import this component like this:
import CarouselComponent from '../CarouselComponent'; //path to your component
<Carousel>
<View>
//any view you want to be rendered in the modal
</View>
</Carousel>

React in-memory Portal

I do want to create a React component tree in memory (not in the DOM) with the same behavior a React Portal has, that is, it should use contexts from the parent component tree.
So is it possible to create something like Portal but instead of render it on a DOM node, "render" it in memory (outside the DOM)?
Note that what I need is the component life-cycle of some components in the tree while the visual part will be hidden, but in my case if I put the component tree in the DOM within a hidden div the performance is not good and then I want to test a different approach.
Two possibilities come to my mind:
1) create a portal to a DocumentFragment
When you use ReactDOM.createPortal, you could point it to a documentFragment in memory rather than an element on the page. The nodes that get created should then be appended to that fragment in memory. Whether or not this meets your criteria or not i'm not sure, but it would look something like this:
class Example extends Component {
constructor (props) {
super(props);
this.fragment = document.createDocumentFragment();
}
render() {
return ReactDOM.createPortal(
this.children,
this.fragment
);
}
}
2) Create a custom reconciler.
If you want the data to be output in some particular format instead of being DOM nodes, you could create a custom reconciler. This is non-trivial thing to do and uses the react-reconciler package, which the react team describes as "experimental", but it would give you very precise control of what to do with the results of the render.
If this is something you want to do you can read some at the react-reconciler readme, and it may be useful to look at the configuration files that are used for other reconcilers (see the "host config" links near the bottom of the readme)

class name convention in react material-ui framework

Is there a class name convention used in material ui library? I'm currently using material-ui-next. I notice class names like "MuiFormControl-root-124" all over the place with numbers appended to class name. For Paper element "MuiPaper-root-18 MuiPaper-shadow2-22 MuiPaper-rounded-19". I just can't see a pattern here.
Is there a convention which I'm missing. It would be easier to understand this framework if it made sense like Bootstraps grid classes. All help much appreciated. Thank you.
In material-ui v1, class names are non-deterministically generated at run time, so there is no convention you should adhere to. That's described here in the docs:
You may have noticed that the class names generated by our styling solution are non-deterministic, so you can't rely on them to stay the same.
However, that does not matter because you should never be using raw CSS class names in the first place. Instead, you use withStyles to set the appropriate styles for each component:
import { withStyles } from 'material-ui/styles';
// Define the CSS styles you which to apply to your component
const styles = {
root: {
backgroundColor: 'red',
},
};
class MyComponent extends React.Component {
render () {
// withStyles automatically provides the classes prop, which
// will contain the generated CSS class name that you can match
// to your component
return <div className={this.props.classes.root} />;
}
}
export default withStyles(styles)(MyComponent);
These non-deterministic class names have technical benefits, including improved performance:
Thanks to the non-deterministic nature of our class names, we can implement optimizations for development and production. They are easy to debug in development and as short as possible in production.
You should note that this happens because material-ui takes a fundamentally different approach to styling than a library like Bootstrap. While Bootstrap has a CSS library with defined class names that get applied to each element, material-ui uses CSS in JS to inject styling. This allows CSS to be defined and stored alongside the JavaScript definition of each component.

How to import a component or file in React using variables?

I'm building a web app using React that shows the blueprint for the building you select, in an already selected campus.
I have a "Content" component that loads the campus or building map, depending what you chose.
The "BuildingMap" component needs to load a specific blueprint according to what building you selected. It gets the props.building with the name of the building but I don't know how to load a component using that variable.
I have tried import, fetch and require but nothing seems to work.
Please help.
My code looks something like this:
//Content Component
<BuildingMap building={selectedBuilding} campus={selectedCampus} />
//BuildingMap Component
import *MyBlueprint* from (specific folder depending on the campus selected)
class BuildingMap extends React.Component {
render(){
return (
<div className="blueprint" id={this.props.building}>
{*MyBlueprint*}
</div>
)
}
}
Unfortunately, you cannot import/require components dynamically in React environment.
Depending on how many buildings/blueprints there are, it's possible to import them one by one, create component-building map and pick component by building ID.
If there are many/infinite components to load, I would surely pick another method - don't know content of your problem.
import BlueprintA from './BlueprintA'
import BlueprintB from './BlueprintB'
import BlueprintC from './BlueprintC'
// ...
class BuildingMap extends React.Component {
render(){
const C = {
buildingA: BlueprintA,
buildingB: BlueprintB,
buildingC: BlueprintC,
// ...
}[this.props.building]
return (
<div className="blueprint" id={this.props.building}>
<C />
</div>
)
}
}
This question is pretty old but as I was looking for how to solve the same problem let me give my answer. It can be done with dynamic import React.lazy:
const OtherComponent = React.lazy(() => import('./OtherComponent'));
See more details here: https://reactjs.org/docs/code-splitting.html#reactlazy
To add to #Andreyco's answer:
Using a lookup table of string IDs/names to component classes is a typical React idiom. One common use case is a modal manager component that can render multiple different types of modals. For some examples, see Dan Abramov's answer at "How can I render a modal dialog in Redux?" (not Redux-specific), as well as some of the related articles in the React Component Patterns#Modal Dialogs and Redux Techniques#UI sections of my React/Redux links list.
Per #azium's comment: it is definitely possible to use dynamic importing (via require.ensure() or the new import() function) to load chunks at runtime, and you could add the exports from those dynamically imported chunks into a lookup table when they are loaded.

Can React props contain custom classes?

We have a (TypeScript) class that manages a set of parameters (contains parameter type, default/min/max values, descriptions, ...) that we are using in quite a few places in our code.
For our GUI we have started to use React. One of the components we're building is essentially some kind of parameter property panel, and for the props of my component I would like to use our custom ParameterSet class.
Should this just work? Or do props need to be simple types?
Does React do internal things that will stop working properly when props contain custom classes that are more complex than simple types?
Just like #Rob has commented you, props can store whatever. You have to see them like an object that can have unlimited named references.
You can validate their types (if you want), which when running your app in development will let you know if these types are correct:
MyComponent.propTypes = {
element: React.PropTypes.element.isRequired,
}
You can watch for changes, see React lifecycle:
componentWillReceiveProps(newProps) {
// handle props change
}

Resources