Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Redux and inheritance

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.

like image 599
Omid Avatar asked Jan 01 '23 14:01

Omid


2 Answers

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.

like image 109
B12Toaster Avatar answered Jan 05 '23 06:01

B12Toaster


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);
like image 43
Shubham Khatri Avatar answered Jan 05 '23 08:01

Shubham Khatri