问题
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 soBoard.prototype
isn't used by the object. Normally, a constructor function shouldn't return anything, and should use the objectnew
created when calling it, which it receives asthis
. - You're not giving
React.Component
its chance to initialize the instance. - You're not setting
constructor
onBoard.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