最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Correct way to inherit React components - Stack Overflow

programmeradmin3浏览0评论

I understand that my question is a little bit biased, but I am very new in Javascript and prototypes, and I read about it, but I don't really understand how to apply that techniques to my practical problems. So an example would be very helpful. So I have a React ponent, that basically looks like that:

var Component1 = React.createClass({

getInitialState: function () {
        return ({
            searchable: true,
        })
    },

function1: function () {
        return ({
            somevalue
        })
    },

render: function () {

        var redText = {
            color: 'red'
        };

        var redBorder = {
            color: 'red',
            border: '1px solid red'

        };

        return (
                <form>
                    <div>
                        <a onClick={this.props.handleAddClick}>Something</a>
                    </div>

                    <div>
                        <label>Some label</label>
                        <input type="text"/>
                    </div>
               </form> ) 
});

I also have Component2 which is basically absolutely the same, but has one additional <input/> inside the return of its render function.

I also have Component3, which shares same functions, but has different render() function.

So how to apply inheritance here and avoid copy-paste 3 times? I just miss some practical illustration, so I'd appreciate it.

Edit1____________________________________________________ So I tried to implement Prototype inheritance as per the first answer, but it seems React doesn't see these functions: getInitialState() is null, initial state is null after rendering. What's wrong with this approach?

I also tried to go according to the textbook and did:

function MyPrototype() {};
MyPrototype.prototype.getInitialState = function () {
    return ({
        someProperty: true;
    })
};

function Component1() {};
Component1.prototype = Object.create(MyPrototype.prototype);
Component1.prototype.render = function () {
    console.log(this);
    return (<div></div>)};

var MyComponent1 = React.createClass(new Component1());

But when I open my browser, I get an error: Uncaught Invariant Violation: createClass(...): Class specification must implement arendermethod.

What am I doing wrong this way?

Edit2_______________________________________________

Actually, I see that React doesn't support mixins neither prototypes. Composition should be used instead. It's explained in this article: Dan Abramov's article Mixins Are Dead. Long Live Composition

I understand that my question is a little bit biased, but I am very new in Javascript and prototypes, and I read about it, but I don't really understand how to apply that techniques to my practical problems. So an example would be very helpful. So I have a React ponent, that basically looks like that:

var Component1 = React.createClass({

getInitialState: function () {
        return ({
            searchable: true,
        })
    },

function1: function () {
        return ({
            somevalue
        })
    },

render: function () {

        var redText = {
            color: 'red'
        };

        var redBorder = {
            color: 'red',
            border: '1px solid red'

        };

        return (
                <form>
                    <div>
                        <a onClick={this.props.handleAddClick}>Something</a>
                    </div>

                    <div>
                        <label>Some label</label>
                        <input type="text"/>
                    </div>
               </form> ) 
});

I also have Component2 which is basically absolutely the same, but has one additional <input/> inside the return of its render function.

I also have Component3, which shares same functions, but has different render() function.

So how to apply inheritance here and avoid copy-paste 3 times? I just miss some practical illustration, so I'd appreciate it.

Edit1____________________________________________________ So I tried to implement Prototype inheritance as per the first answer, but it seems React doesn't see these functions: getInitialState() is null, initial state is null after rendering. What's wrong with this approach?

I also tried to go according to the textbook and did:

function MyPrototype() {};
MyPrototype.prototype.getInitialState = function () {
    return ({
        someProperty: true;
    })
};

function Component1() {};
Component1.prototype = Object.create(MyPrototype.prototype);
Component1.prototype.render = function () {
    console.log(this);
    return (<div></div>)};

var MyComponent1 = React.createClass(new Component1());

But when I open my browser, I get an error: Uncaught Invariant Violation: createClass(...): Class specification must implement arendermethod.

What am I doing wrong this way?

Edit2_______________________________________________

Actually, I see that React doesn't support mixins neither prototypes. Composition should be used instead. It's explained in this article: Dan Abramov's article Mixins Are Dead. Long Live Composition

Share Improve this question edited May 3, 2016 at 2:02 Battle_Slug asked May 2, 2016 at 0:14 Battle_SlugBattle_Slug 2,1052 gold badges36 silver badges61 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8

In React, inheritance for ponents is severely discouraged.
React is much better suited for expressing the same relationships via position.

Here is an example of using position:

class Button extends Component {
  render() {
    return (
      <div className='Button' style={{ color: this.props.color }}>
        {this.props.children}
      </div>
    )
  }
}

class DeleteButton extends Component {
  render() {
    return (
      <Button color='red'>Delete</Button>
    )
  }
}

Note how DeleteButton uses the look and feel of Button without inheriting from it. Instead, Button defines its configurable parts via props, and DeleteButton supplies those props. In the actual DOM, both <Button /> and <DeleteButton /> would render to a single DOM node—the recursive resolution happens at the render() time, and this is the core idea of React.

In fact, if you don’t need lifecycle hooks or local state, you may even define ponents as functions:

function Button({ color, children }) {
  return (
    <div className='Button' style={{ color }}>
      {children}
    </div>
  )
}

function DeleteButton() {
  return (
    <Button color='red'>Delete</Button>
  )
}

You can even mix classes with functions. This would be impossible with inheritance, but works great with position.

As for your specific use cases:

I also have Component2 which is basically absolutely the same, but has one additional <input/> inside the return of its render function.

You can have your Component1 accept this.props.children and use them in the return value of render() method, and have Component2 render to <Component1><input /></Component>. This is very similar to what I showed above. You also don’t have to use the children prop—you can pass a React element in any prop, e.g. <Component1 footer={<input />} />, and then you can use this.props.footer inside Component1.

I also have Component3, which shares same functions, but has different render() function.

If they share any other code (e.g. utilities that calculate some data), move that code outside ponents into a shared module, and import it from both ponents.

If they share any UI, extract it into yet another ponent, and use it from both your ponents.

发布评论

评论列表(0)

  1. 暂无评论