Beispiel #1
0
        protected PureComponent(TProps props, params Union <ReactElement, string>[] children)
        {
            // To ensure that a single "template" (ie. React component) is created per unique class, a static "_reactComponentClasss" dictionary is maintained. If it has no entry
            // for the current type then this must be the first instantiation of that type and so a component class will be created and added to the dictionary, ready for re-use
            // by any subsequent component instances.
            var    currentType = ((object)this).GetType();          // Cast to object first in case derived class uses [IgnoreGeneric] - see http://forums.bridge.net/forum/bridge-net-pro/bugs/3343
            object reactComponentClass;

            if (!_reactComponentClasses.TryGetValue(currentType, out reactComponentClass))
            {
                reactComponentClass = ReactComponentClassCreator.CreateClass(this, baseComponent: typeof(PureComponent <TProps>));
                _reactComponentClasses[currentType] = reactComponentClass;
            }

            // Now that the React component class is certain to have been defined (once per unique C# component class), this instance requires a React element to be created
            // for it. The internal React mechanism means that the component's constructor will not be executed, which is why ALL configuration options for a component must
            // be contained within the props. Note: In most cases where children are specified as a params array, we don't want the "children require unique keys" warning
            // from React (you don't get it if you call DOM.Div(null, "Item1", "Item2"), so we don't want it in most cases here either - to achieve this, we prepare an
            // arguments array and pass that to React.createElement in an "apply" call.
            Array createElementArgs = new object[] { reactComponentClass, ComponentPropsHelpers.WrapProps(props) };

            if (children != null)
            {
                createElementArgs = createElementArgs.Concat(children);
            }
            _reactElement = Script.Write <ReactElement>("React.createElement.apply(null, createElementArgs)");
        }
Beispiel #2
0
        protected StatelessComponent(TProps props, params Union <ReactElement, string>[] children)
        {
            // When preparing the "_reactStatelessRenderFunction" reference, a local "reactStatelessRenderFunction" alias is used - this is just so that the JavaScript
            // code further down (which calls React.createElement) can use this local alias and not have to know how Bridge stores static references.
            Func <TProps, ReactElement> reactStatelessRenderFunction;
            var currentType = ((object)this).GetType();             // Cast to object first in case derived class uses [IgnoreGeneric] - see http://forums.bridge.net/forum/bridge-net-pro/bugs/3343

            if (!_reactStatelessRenderFunctions.TryGetValue(currentType, out reactStatelessRenderFunction))
            {
                reactStatelessRenderFunction = CreateStatelessRenderFunction();
                _reactStatelessRenderFunctions[currentType] = reactStatelessRenderFunction;
            }

            // When we pass the props reference to React.createElement, React's internals will rip it apart and reform it - which will cause problems if TProps is a
            // class with property getters and setters (or any other function) defined on the prototype, since members from the class prototype are not maintained
            // in this process. Wrapping the props reference into a "value" property gets around this problem, we just have to remember to unwrap them again when
            // we render. In most cases where children are specified as a params array, we don't want the "children require unique keys" warning from React (you
            // don't get it if you call DOM.Div(null, "Item1", "Item2"), so we don't want it in most cases here either - to achieve this, we prepare an arguments
            // array and pass that to React.createElement in an "apply" call. Similar techniques are used in the stateful component.
            Array createElementArgs = new object[] { reactStatelessRenderFunction, ComponentPropsHelpers.WrapProps(props) };

            if (children != null)
            {
                createElementArgs = Script.Write <Array>("{0}.concat({1})", createElementArgs, children);                // Since upgrading from Bridge 1.7.6 to 1.7.9, I'm getting an error that Concat doesn't exist so I'll just do this
            }
            _reactElement = Script.Write <ReactElement>("React.createElement.apply(null, {0})", createElementArgs);
        }
		/// <summary>
		/// This should only be used by the React.DOM factory method overloads - as such, I haven't created separate strongly-typed method signatures for StatelessComponent and PureComponent,
		/// I've rolled them together by having a single signature that takes an object set. This means that this method could feasibly be called with an object of references without the
		/// private "_reactElement" property, but no-one should be able to call this anyway so that's very low risk. Note that this won't work with the Component base class, it causes
		/// React to throw a "Maximum call stack size exceeded" error that I haven't been able to get to the bottom of yet (the ToChildComponentArray extension methods only supported
		/// StatelessComponent and PureComponent, so I'm ok for now with only supporting DOM factory methods that handle dynamic sets of StatelessComponent and PureComponent but
		/// not Component)
		/// </summary>
		internal static ReactElement[] ToReactElementArray(IEnumerable<object> components)
		{
			if (components == null)
				throw new ArgumentNullException("components");

			var componentsArray = components.ToArray();
			var reactElements = new ReactElement[componentsArray.Length];
			/*@
			for (var i = 0; i < componentsArray.length; i++) {
				reactElements[i] = (componentsArray[i] == null) ? null : componentsArray[i]._reactElement;
			}
			 */
			return reactElements;
		}
Beispiel #4
0
        /// <summary>
        /// This should only be used by the React.DOM factory method overloads - as such, I haven't created separate strongly-typed method signatures for StatelessComponent and PureComponent,
        /// I've rolled them together by having a single signature that takes an object set. This means that this method could feasibly be called with an object of references without the
        /// private "_reactElement" property, but no-one should be able to call this anyway so that's very low risk. Note that this won't work with the Component base class, it causes
        /// React to throw a "Maximum call stack size exceeded" error that I haven't been able to get to the bottom of yet (the ToChildComponentArray extension methods only supported
        /// StatelessComponent and PureComponent, so I'm ok for now with only supporting DOM factory methods that handle dynamic sets of StatelessComponent and PureComponent but
        /// not Component)
        /// </summary>
        internal static ReactElement[] ToReactElementArray(IEnumerable <object> components)
        {
            if (components == null)
            {
                throw new ArgumentNullException("components");
            }

            var componentsArray = components.ToArray();
            var reactElements   = new ReactElement[componentsArray.Length];

            /*@
             * for (var i = 0; i < componentsArray.length; i++) {
             *      reactElements[i] = (componentsArray[i] == null) ? null : componentsArray[i]._reactElement;
             * }
             */
            return(reactElements);
        }
Beispiel #5
0
 public extern static void Render(ReactElement element, Element container);
Beispiel #6
0
 public extern static void Render(ReactElement element, Element container, Action callback);
Beispiel #7
0
 public extern static void Render(ReactElement element, Element container);