How to implement “normal” ES5 prototypal inheritance in React?

≯℡__Kan透↙ 提交于 2019-12-24 02:06:16

问题


I am under the impression that ES6 classes are basically a syntactic sugar around the ES5 objects system. As I am trying to run React without a transpiler, I figured that I could use just use the old syntax for defining object "classes" that "inherit" from React.Component.

    var Board = function(props, state) {
        var instance = {};

        instance.props = props;
        instance.context = state;

        return(instance);           
    };

    Board.prototype = Object.create(React.Component.prototype);

    Board.prototype.render = function() {
        return(
            // ...stuff
        )               
    };

But that does not work!

react.js:20478 Warning: Board(...): No `render` method found on the returned component instance: you may have forgotten to define `render`
react.js:6690 Uncaught TypeError: inst.render is not a function(…)

I found alternatives in this gist, and the following works:

    var Board = function(props, state) {
        var instance = Object.create(React.Component.prototype);

        instance.props = props;
        instance.context = state;

        instance.prototype.render = function() {
            return(
                // ...stuff
            )               
        };

        return(instance);           
    };

I have also found out that I can use the React.createClass helper.

But I still would like to understand why React would not handle classes defined in such a common way. It seems to me that ES6 classes are instanciated before being used. I see no reason why ES5-style classes would not be instanciated as well, with similar results.


回答1:


Why is “normal” ES5 prototypal inheritance not supported in React?

It is, although using React.createClass is probably your better option. It's just that the code in your question isn't doing the standard ES5 class-like inheritance tasks. In particular:

  • You're returning an instance of a plain object, not an instance of Board, and so Board.prototype isn't used by the object. Normally, a constructor function shouldn't return anything, and should use the object new created when calling it, which it receives as this.
  • You're not giving React.Component its chance to initialize the instance.
  • You're not setting constructor on Board.prototype (although I don't know whether React cares; a lot of things don't).

It works if you set it up in the normal way. Here's an ES5 example without React.createClass, see comments:

// The component
function Foo(props) {
    // Note the chained superclass call
    React.Component.call(this, props);
}

// Set up the prototype
Foo.prototype = Object.create(React.Component.prototype);
Foo.prototype.constructor = Foo; // Note

// Add a render method
Foo.prototype.render = function() {
    return React.createElement("div", null, this.props.text);
};

// Use it
ReactDOM.render(
    React.createElement(Foo, {
        text: "Hi there, the date/time is " + new Date()
    }),
    document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>


来源:https://stackoverflow.com/questions/40366024/how-to-implement-normal-es5-prototypal-inheritance-in-react

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!