ReactClass -> ComponentClass; add tests to react-tests.ts

This commit is contained in:
Vincent Siao
2014-12-02 18:11:15 -08:00
parent a99c1ad839
commit 7f4cdee628
3 changed files with 308 additions and 219 deletions
+140 -58
View File
@@ -1,64 +1,152 @@
/// <reference path="react.d.ts" />
import React = require("react");
interface Props {
hello: string;
world?: string;
foo: number;
bar: boolean;
}
interface State {
inputValue?: string;
seconds?: number;
}
interface MyComponentInstance extends React.ComponentInstance<Props, State> {
reset(): void;
}
var props: Props = {
hello: "world",
foo: 42,
bar: true
};
var container: Element;
var INPUT_REF: string = "input";
//
// Top-Level API
// --------------------------------------------------------------------------
var reactClass: React.ComponentClass<Props> = React.createClass<Props>({
getDefaultProps: () => {
return <Props>{
hello: undefined,
world: "peace",
foo: undefined,
bar: undefined
};
},
getInitialState: () => {
return {
inputValue: "React.js",
seconds: 0
};
},
reset: () => {
this.replaceState(this.getInitialState());
},
render: () => {
return React.DOM.div(null,
React.DOM.input({
ref: INPUT_REF,
value: this.state.inputValue
}));
}
});
var reactElement: React.ReactElement<Props> =
React.createElement<Props>(reactClass, props);
var reactFactory: React.Factory<Props> =
React.createFactory<Props>(reactClass);
var reactInstance: React.Instance<Props> =
React.render<Props>(reactElement, container);
var unmounted: boolean = React.unmountComponentAtNode(container);
var str: string = React.renderToString(reactElement);
var markup: string = React.renderToStaticMarkup(reactElement);
var notValid: boolean = React.isValidElement(props); // false
var isValid = React.isValidElement(reactElement); // true
React.initializeTouchEvents(true);
//
// React Elements
// --------------------------------------------------------------------------
var type = reactElement.type;
var elementProps: Props = reactElement.props;
var key = reactElement.key;
var ref: string = reactElement.ref;
var factoryElement: React.ReactElement<Props> = reactFactory(elementProps);
//
// React Components
// --------------------------------------------------------------------------
var displayName: string = reactClass.displayName;
var defaultProps: Props = reactClass.getDefaultProps();
var propTypes: React.ValidationMap<Props> = reactClass.propTypes;
//
// Component API
// --------------------------------------------------------------------------
var htmlElement: Element = reactInstance.getDOMNode();
var divElement: HTMLDivElement = reactInstance.getDOMNode<HTMLDivElement>();
var isMounted: boolean = reactInstance.isMounted();
reactInstance.setProps(elementProps);
reactInstance.replaceProps(props);
var componentInstance: React.ComponentInstance<Props, State> =
<React.ComponentInstance<Props, State>>reactInstance;
var initialState: State = componentInstance.state;
componentInstance.setState({ inputValue: "!!!" });
componentInstance.replaceState({ inputValue: "???", seconds: 60 });
componentInstance.forceUpdate();
var inputRef: React.Instance<React.HTMLAttributes> =
componentInstance.refs[INPUT_REF];
var value: string = inputRef.getDOMNode<HTMLInputElement>().value;
var myComponentInstance = <MyComponentInstance>componentInstance;
myComponentInstance.reset();
//
// PropTypes
// --------------------------------------------------------------------------
var PropTypesSpecification: React.ComponentSpec<any, any> = {
propTypes: {
// You can declare that a prop is a specific JS primitive. By default, these
// are all optional.
optionalArray: React.PropTypes.array,
optionalBool: React.PropTypes.bool,
optionalFunc: React.PropTypes.func,
optionalNumber: React.PropTypes.number,
optionalObject: React.PropTypes.object,
optionalString: React.PropTypes.string,
// Anything that can be rendered: numbers, strings, components or an array
// containing these types.
optionalNode: React.PropTypes.node,
// A React element
optionalElement: React.PropTypes.element,
// You can also declare that a prop is an instance of a class. This uses
// JS's instanceof operator.
optionalMessage: React.PropTypes.instanceOf(Date),
// You can ensure that your prop is limited to specific values by treating
// it as an enum.
optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),
// An object that could be one of many types
optionalEnum: React.PropTypes.oneOf(["News", "Photos"]),
optionalUnion: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number,
React.PropTypes.instanceOf(Date)
]),
// An array of a certain type
optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
// An object with property values of a certain type
optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
// An object taking on a particular shape
optionalObjectWithShape: React.PropTypes.shape({
color: React.PropTypes.string,
fontSize: React.PropTypes.number
}),
// You can chain any of the above with `isRequired` to make sure a warning
// is shown if the prop isn't provided.
requiredFunc: React.PropTypes.func.isRequired,
// A value of any data type
requiredAny: React.PropTypes.any.isRequired,
// You can also specify a custom validator. It should return an Error
// object if the validation fails. Don't `console.warn` or throw, as this
// won't work inside `oneOfType`.
customProp: function(props: any, propName: string, componentName: string) {
if (!/matchme/.test(props[propName])) {
return new Error('Validation failed!');
return new Error("Validation failed!");
}
return null;
}
@@ -68,47 +156,41 @@ var PropTypesSpecification: React.ComponentSpec<any, any> = {
}
};
React.createClass(PropTypesSpecification);
//
// Example from http://facebook.github.io/react/
// --------------------------------------------------------------------------
var mountNode: Element;
interface HelloMessageProps {
name: string;
interface TimerState {
secondsElapsed: number;
}
var HelloMessage = React.createClass<HelloMessageProps>({
displayName: 'HelloMessage',
render: function() {
return React.DOM.div(null, "Hello ", (<React.ReactInstance<HelloMessageProps>>this).props.name);
}
});
var HelloMessageFactory = React.createFactory(HelloMessage)
React.render(HelloMessageFactory({ name: "John" }), mountNode)
var Timer = React.createClass({displayName: 'Timer',
getInitialState: function() {
return {secondsElapsed: 0};
interface TimerInstance extends React.ComponentInstance<{}, TimerState> {
}
var Timer = React.createClass({
displayName: "Timer",
getInitialState: () => {
return { secondsElapsed: 0 };
},
tick: function() {
var me = <React.ComponentInstance<any, {secondsElapsed: number}>>this;
tick: () => {
var me = <TimerInstance>this;
me.setState({
secondsElapsed: me.state.secondsElapsed + 1
});
},
componentDidMount: function() {
componentDidMount: () => {
this.interval = setInterval(this.tick, 1000);
},
componentWillUnmount: function() {
componentWillUnmount: () => {
clearInterval(this.interval);
},
render: function() {
render: () => {
var me = <TimerInstance>this;
return React.DOM.div(
null,
"Seconds Elapsed: ",
(<React.ComponentInstance<any, {secondsElapsed: number}>>this).state.secondsElapsed
me.state.secondsElapsed
);
}
});
var mountNode: Element;
React.render(React.createElement(Timer, null), mountNode);