Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I extend a "connected" component?

Tags:

reactjs

redux

My situation is, I have the Navigation component, which is the base, and is listening to the Navigations state(Redux). It should be extended to HorizontalNavigation and VerticalNavigation, for easy reusable code in the future.

My problem is, right now I already have the "final" version of Navigation.jsx and I can extend it, as a class, but can't override it's methods. It triggers the super(Navigation) method and not the final one. I need to override the methods in Horizontal or Vertical components.

There is no code erros on console, so it isn't something breaking, but that I don't know how to handle how to extend it.

Navigation.jsx

import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import { connect } from 'react-redux';

import { itemAction, stageAction } from 'Store/Actions/Actions';

class Navigation extends Component {
    // ACTIONS
    leftAction () {
        this.onLeftAction();
    }
    onLeftAction () {}

    rightAction () {
        this.onRightAction();
    }
    onRightAction () {}

    downAction () {
        this.onDownAction();
    }
    onDownAction () {}

    upAction () {
        this.onUpAction();
    }
    onUpAction () {}

    // STAGES
    nextStage (slug) {
        this.goToStage(slug);
    }

    previousStage (slug) {
        this.goToStage(slug);
    }

    goToStage (slug) {
        // Just for illustration purpose
        // let { dispatch } = this.props;
        // dispatch(stageAction(slug));
    }

    // ITEMS
    nextItem (index) {
        this.goToItem(index);
    }

    previousItem (index) {
        this.goToItem(index);
    }

    goToItem (index) {
        // Just for illustration purpose
        // let { dispatch } = this.props;
        // dispatch(itemAction(index));
    }

    render () {
        return ();
    }
}

function mapStateToProps (state, props) {
    navigation: state.Navigations[props.slug]
}

export default connect(mapStateToProps)(Navigation);

Horizontal.jsx

import React from 'react';
import Navigation from 'Components/Navigation/Navigation';

class HorizontalNavigation extends Navigation {
    onLeftAction (previousItemIndex) {
        this.previousItem(previousItemIndex);
    }

    onRightAction (nextItemIndex) {
        this.nextItem(nextItemIndex);
    }

    onTopAction (slug) {
        this.previousStage(slug);
    }

    onDownAction (slug) {
        this.nextStage(slug);
    }
}

export default HorizontalNavigation;

The VerticalNavigation would be the opposite. Left and right for stage; up and down for items.

I don't want to reuse the Navigation component each time I could use Horizontal or Vertical, and rewrite the same exact logic over and over again.

like image 499
klauskpm Avatar asked Mar 13 '17 22:03

klauskpm


People also ask

Can you extend a component in React?

Using the extends keyword, you can allow the current component to access all the component's properties, including the function, and trigger it from the child component. This example creates one component called ParentClass. jsx. ParentClass extends the component from React as React.

Can you extend a functional component?

A functional component is just a function, you know, a render function. So extending a functional component means you will override the render function, and.. it means that you override the entire functional component (because it's just a render function), then you extend nothing.

What does extending a component mean?

This Component refers to a specific class implementation maintained by react . Extending Component will give you access to functions like componentDidMount , componentDidUpdate , componentWillUnmount and render .

What is a connected component React?

A Connected Container is a React component that interacts with Redux. It is called connected because a connect function is used to inject the exported component with Redux provided state and props.

What is a connected component?

In connected components, all the nodes are always reachable from each other. 3. Few Examples In this section, we’ll discuss a couple of simple examples. We’ll try to relate the examples with the definition given above.

When does a set of nodes form a connected component?

A set of nodes forms a connected component in an undirected graph if any node from the set of nodes can reach any other node by traversing edges. The main point here is reachability.

What is a connected component in 2D graph?

2. Connected Component Definition A connected component or simply component of an undirected graph is a subgraph in which each pair of nodes is connected with each other via a path. Let’s try to simplify it further, though.

Are connected component sets pairwise disjoint?

Finally, connected component sets are pairwise disjoint. That means if we take the intersection between two different connected component sets then the intersection will be equals to an empty set or a null set. Let’s consider the connected components of graph again.


2 Answers

I'm using the Higher-Order Component pattern, exporting a function to connect the extended component, eg:

import { connect as reduxConnect } from 'react-redux'
...

export class Navigation extends Component{
...

export function connect(Component){
  return reduxConnect(
    (state, props)=>({...})
  )(Component);
}

export default connect(Navigation)

And in the Horizontal.jsx you could do

import { Navigation, connect } from './Navigation';

class Horizontal extends Navigation{
...

export default connect(Horizontal);

This way, you keep the connect(mapStateToProps) in one place.

like image 140
brunettdan Avatar answered Oct 11 '22 08:10

brunettdan


This is a fun one. At the bottom of Navigation, you're exporting the connecting component, which in essence is exporting the class created in connect, which is not the same class as Navigation. So, when you extend the default exported class, you're actually extending the connect class. That's a mouthful.

To get this to work, you could also export your class (in addition to export default connect(mapStateToProps)(Navigation); at the bottom:

export class Navigation extends Component {

Then to extend it, you can do:

import { Navigation } from './Navigation';

class Horizontal extends Navigation {
  // ...

However, you would also need connect the Horizontal component as well in order to get the right props from redux.

If you don't want to use connect, you could take in props to your Navigation component that changes how those up/down/left/right actions work, then you could create a Horizontal/Vertical component that passes in the right props. Something like:

class Horizontal extends React.Component {
  constructor(props, context) {
    super(props, context);

    this.onUp = this.onUp.bind(this);
    this.onDown = this.onDown.bind(this);
    this.onLeft = this.onLeft.bind(this);
    this.onRight = this.onRight.bind(this);
  }
  onUp() {}
  onDown() {}
  onLeft() {}
  onRight() {}
  render() {
    return (
      <Navigation onUp={this.onUp} onDown={this.onDown} onLeft={this.onLeft} onRight={this.onRight} />
    );
  }
);
like image 38
James Ganong Avatar answered Oct 11 '22 08:10

James Ganong