I'm really wondering why there is nothing about Redux and how to deal with inheritance. If I have a base component:
class BaseComponent extends Component{
}
then all other components are extending BaseComponent:
class Todo extends BaseComponent {
}
I want to simply connect the BaseComponent to it's own reducer so every other component which extends it, also can access the same props and states.
Unfortunately can't find any documentation out there. I have no idea if this is a right concept or not.
With react you usually will not further inherit from your own components.
Here is a quote from the official docs on Composition vs Inheritance:
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.
If you want to reuse non-UI functionality between components, we suggest extracting it into a separate JavaScript module. The components may import it and use that function, object, or a class, without extending it.
That being said, if you still want to deviate from the recommended way and have a base component for shared functionality, it is possible. You are still on the "safe side" (i.e. it will most likely not cause too much confusion or trouble) if you (1) reduce the functionality in your base to the least common denominator needed by most of its children (2) do not keep any shared state in your base component (3) do not use arrow functions in your base component and if you (4) make sure to keep your lifecycle methods and connect in your child components to avoid unexpected behaviours.
Performing a connect in your base class, as you are planning to do it, would be problematic as connect returns a newly wrapped component which acts as an owner of your actual BaseComponent (see how connect works). Therefore, you will lose the ability to access your class methods, in your ChildComponents. Also, most likely other bad things will happen because you now independently inject and manage state and lifecycles on two levels (child and base). – Therefore, your best shot, when using a custom BaseComponent, would be to not put connect in your parent but let the child handle the connect.
Here is also a blog article by Dan Abramov worth reading that discusses the question of inheritance in react. His main concerns are that multi-level hierarchies are harder to refactor, name clashes will arise if a parent class later adds methods with names that some child class already uses, sharing logic between child and parent methods makes it harder to understand the code. Overall he suggests to rely on functional programming style.
So what are my recommendations for React components?
You can use class in your JS if you don’t inherit twice and don’t use super.
Prefer to write React components as pure functions when possible.
Use ES6 classes for components if you need the state or lifecycle hooks.
In this case, you may only extend React.Component directly.
Give your feedback to the React team on the functional state proposals.
Generally speaking, whether or not hierarchies are good in OOP programming is a highly debated field.
Inheritance is not widely preferred and encouraged in React and hence you don't find much documentation about this online. A better way to achieve what you want is to export a container which you can then wrap as a HOC to any component you wish to use it for
connectContainer.js
const mapStateToProps = state => {
return {}; // return data you want from reducers
}
const mapDispatchToProps = {}; // define action creators you want to pass here
export default connect(mapStateToProps, mapDispatchToProps);
Now in any component you wish to use the same container properties, you can use them like
import connectHOC from './connectContainer';
class Todo extends React.Component {
}
export connectHOC(Todo);
Related
I know it's possible to use RRP and HOC patterns with functional components, my question actually is, are there any point on doing that? Making some researches I read React/Custom Hooks can essentially handle what render props did in the past with Class Components. The fact is there is not very much information about these patterns in relation to Functional Components, almost every example out there use Class Components, so I was wondering if there's a relevant place to it in Functional Composition.
This is how I would put it: In most of the cases, you would use hooks; in some specific situations you may use, higher-order components.
From a control perspective, hooks provide more flexibility for the user of the code. It means there is a possibility that they could be used in not-intended way. But I would call it a theoretical possibility.
If your reusable logic has JSX as well as some custom logic, may be providing higher-order component or, even render props, makes more sense. Of course this means, that you should have extremely well defined lifecycle for your component and you would not like to provide complete control to the user.
An example would be react-router which is combination of both hooks and render props where applicable.
I'm doing on migration all of my class component to functional component using mobx-react
I wonder all of my components should wrapped by observer or not.
I guess there might be three scenarios.
observable states are being called and used.
observable states are been passed into props
purely stateless component.
let's say all of three components above are functional component.
Should I wrap all the components above with observer of mobx-react?
cf) Is there any articles or benchmarking compares to #observer decorators of mobx ?
Basically this https://mobx.js.org/refguide/observer-component.html#when-to-apply-observer and https://mobx.js.org/best/pitfalls.html#use-observer-on-all-components-that-render-observable-s
You usually wrap everything in observer, exception might be components which only render primitives or something like this, but it is tedious to track it so usually you just wrap all of them.
Mobx's guideline is to put it on any component that reads observable data:
https://mobx.js.org/react-integration.html#always-read-observables-inside-observer-components
If I understood the question correctly, the right answer is on the documentation Mobx site:
You might be wondering, when do I apply observer?
You might be wondering, when do I apply observer? The rule of thumb is: apply observer to all components that read observable data.
observer only enhances the component you are decorating, not the components called by it. So usually all your components should be wrapped by observer. Don't worry, this is not inefficient. On the contrary, more observer components make rendering more efficient as updates become more fine-grained.
p.s.:
there are broken links in first reply,
I need to know what is most convenient way to implement. In my case, the parent component and the children component are using the same properties and states. My doubt is:
1. Passing the properties from the parent component.
2. Use the decorators to set a properties values in the children component.
advantages and disadvantages of different cases? Thanks!
What you're discovering is the distinction between Components and Containers. Containers are what you refer to as "with decorators" and Components are those without. There is a lot of discussion around best practices on these topics, and those keywords should make it easy to find lots of opinions.
Typically, the standard is that you should prioritize Components over Containers. Components are abstract and reusable if created in the right way. For instance, given your first example, I would modify it slightly to look more like this;
class ComponentParent extends React.Component {
//...
render() {
<ComponentChildren onSomeEvent={this.props.optionActions.anyAction}/>;
}
}
class ComponentChildren extends React.Component {
//...
someMethod() {
this.props.onSomeEvent();
}
}
When written this way, ComponentChildren can now be reused and given a new definition of onSomeEvent to interact with your app in a new way. Building all of your components in this style will eventually lead to a library-like codebase, where code becomes extremely reusable.
Hi I am working on some internal project I need to show case multitennacy concept in React. I have site A and B. A would have all platform components and B will inherit A components and also need to have extended functionality. For e.g A have Carousel component which has own functionality I want to introduce some new features like after first slide move I need to make any call backs etc... In React there conepts of HOC and Composition which will work for extending components as there is no inheritience concept.
Although inheritance in react is not as widely applicable as in other frameworks (and react clearly do not recommend this approach as well), yet there is nothing that prohibits you from using inheritance when necessary:
export class BaseComponent extends React.PureComponent
{
// ...
}
export class AdvancedComponent extends BaseComponent
{
// ...
}
Overriding in descendants required methods.
When I develop a React-based web-app, I often separate components into smart and dumb and also into reusable and custom.
Reusable components can be self-sufficient, such as e.g. <RedButton> or <CustomSelect> but they can also be middleware components, such as <FluxStoreBinder>. A middleware component renders its children while adding some functionality to them, usually such as subscribing-reading to/from a Flux store, or wrapping into some other stateful thing. However, some extra work is needed to connect a reusable smart middleware component to a dumb component because their props won't likely match. E.g. a <FluxStoreReader> may "return" a property named data, while a child of type <ToDoList> expects toDoItems.
The question which I want to ask is how to tell a middleware component which content to render in which way. What is the proper and recommended approach? Currently I've seen 3 ways of telling a middleware component how to render its children:
By providing a function through props, such as render={({arg1}) => <Child prop1={arg1}/>}. The features are: you can access own state/props/etc within this function; you can process and re-map props; you can specify which child to render depending on a condition; you can set needed props to the child without having to proxy through the middleware component.
By returning React.cloneElement(children, props) while providing a function to remap props.
By rendering React.cloneElement(children, props) and proxying received props down to the child. Pure component approach, no callbacks. This one don't have the features/flexibility of the above 2, and also requires some extra work: you need another middleware between your middleware and its child to re-map the props.
The fourth option suggested by Mike Tronic is to use higher-order components, which are basically component factories, where one of the required arguments is a child component class. It's almost the same as #3 - but you can't even change the type of the child once you've run the factory.
Which approach did you choose for your application? Why? Please share thoughts.
Would be great to hear a React guys' opinion.
check https://www.youtube.com/watch?v=ymJOm5jY1tQ
http://rea.tech/reactjs-real-world-examples-of-higher-order-components/ and
http://www.darul.io/post/2016-01-05_react-higher-order-components
What are Higher Order Components?
A Higher Order Component is just a React Component that wraps another one.
This pattern is usually implemented as a function, which is basically a class factory (yes, a class factory!), that has the following signature in haskell inspired pseudocode
hocFactory:: W: React.Component => E: React.Component
Where W (WrappedComponent) is the React.Component being wrapped and E (Enhanced Component) is the new, HOC, React.Component being returned.
The “wraps” part of the definition is intentionally vague because it can mean one of two things:
Props Proxy: The HOC manipulates the props being passed to the WrappedComponent W,
Inheritance Inversion: The HOC extends the WrappedComponent W.
We will explore this two patterns in more detail.
What can I do with HOCs?
At a high level HOC enables you to:
Code reuse, logic and bootstrap abstraction
Render Highjacking
State abstraction and manipulation
Props manipulation
We will see this items in more detail soon but first, we are going to study the ways of implementing HOCs because the implementation allows and restricts what you can actually do with an HOC.