reactjs - HOC to add prop if it's a certain type -


i trying write hoc adds prop if it's type. iterating through depth first. when try set prop says it's not extensible, trying add prop of value heehaw:

function fieldlayouthoc(wrappedcomponent: componenttype) {     return (         class fieldlayoutwrap extends wrappedcomponent {             static displayname = wrapdisplayname(wrappedcomponent, 'fieldlayoutwrap')              render() {                 const view = super.render()                 // depth first - stack - last in first out                 // iterate depth first until field found                 const elements = [view]; // stack                  console.log('view:', view);                  while (elements.length) {                     const element = elements.pop();                     const primative = typeof element;                     if (primative === 'object') {                         if (element.type === field) {                             // fields.push(element);                             element.props.value = 'heehaw'; /////// not extensible error here                             console.log('added value heehaww');                         } else {                             if (element.props) {                                 const children = element.props.children;                                 if (children) {                                     if (array.isarray(children)) {                                         elements.push(...children);                                     } else {                                         elements.push(children);                                     }                                 }                             }                         }                     }                 }                  return view;             }         }     ) } 

am doing wrong?

well came own solution. i'm not mutating props, added complication of holding on mutable version of tree. can use cleaning.

function addpropsifhocfactory(predicate) { //   return function addpropsifhoc(wrappedcomponent) { // factory     return (       class fieldlayoutwrap extends wrappedcomponent {          render() {           const view = super.render();           if (!this.addprops) return view;            // depth first - stack - last in first out           // iterate depth first until field found           const viewelementnew = { node: view, parentelement: null };           const tree = [viewelementnew]; // stack // parentelement ref parentelement in elements            const elementsbydepth = {}; // key depth, value array of element's @ depth           const elementsbyparentid = {}; // key elementid of parent           let elementid = 0;           // console.log('view:', view);            let depthmax = 0;            while (tree.length) {             const element = tree.pop();              element.props = element.node.props ? element.node.props : undefined;             element.childrenelements = undefined;             element.clone = undefined;             element.depth = getdepth(element);             element.id = elementid++;             element.needsclone = false; // if true clone, set true if props changed              if (element.depth > depthmax) depthmax = element.depth;              if (!elementsbydepth[element.depth]) {               elementsbydepth[element.depth] = [];             }             elementsbydepth[element.depth].push(element);              const node = element.node;             const primative = typeof node;             if (primative === 'object' && node) {               if (predicate(node)) {                 const addprops = isfunction(this.addprops) ? this.addprops(node) : this.addprops;                 element.props = object.assign({}, node.props ? node.props : undefined, addprops);                 markbranchneedsclone(element);                 console.log('added props node:', element.node);               }             }              if (node.props && node.props.children) {               const children = node.props.children;                const pushchild = child => {                 const parent = element;                 const childelement = {                   node: child,                   parentelement: parent                 }                 tree.push(childelement);                 if (!elementsbyparentid[parent.id]) elementsbyparentid[parent.id] = [];                 elementsbyparentid[parent.id].push(childelement);                  return childelement;               }                if (array.isarray(children)) {                 element.childrenelements = children.map(pushchild);               } else {                 const child = children;                 element.childrenelements = pushchild(child);               }             }           }            // react.cloneelement deepest first if needsclone === true           let depth = depthmax + 1;           while (depth--) {             // console.log('doing elementsbydepth[depth] of depth:', depth);             (const element of elementsbydepth[depth]) {               if (typeof element.node === 'object' && element.node) {                 if (!element.needsclone) {                   element.clone = element.node;                 } else {                   let childrenclones = elementsbyparentid[element.id];                   if (childrenclones) {                     if (childrenclones.length === 1) {                       childrenclones = childrenclones[0].clone;                     } else {                       childrenclones = childrenclones.map(element => element.clone);                     }                   }                   console.log('cloning');                   element.clone = react.cloneelement(element.node, element.props, childrenclones);                 }               } else {                 // string, number etc                 element.clone = element.node;               }             }           }            // console.log('viewelementnew:', viewelementnew);           // console.log('elementsbydepth:', elementsbydepth);           // console.log('elementsbyparentid:', elementsbyparentid);            return viewelementnew.clone;         }       }     )   } }  function isfunction(functiontocheck) {   var gettype = {};   return functiontocheck && gettype.tostring.call(functiontocheck) === '[object function]'; } function getdepth(element) {   let depth = 0;   let elementcur = element;   while (elementcur.parentelement) {     elementcur = elementcur.parentelement;     depth++;   }   return depth; } function markbranchneedsclone(element) {   let elementcur = element;   while (elementcur) {     elementcur.needsclone = true;     elementcur = elementcur.parentelement;   } } 

usage:

import react 'react' import reactdom 'react-dom' import addpropsifhoc 'add-props-if'  // form component class blahdumb extends react.component {   addprops = {     placeholder: 'injected placeholder'   }   render() {     return (       <form>         <label htmlfor="url">url</label>         <div>           <input id="url" type="text" />           yeppers         </div>         <div>           <input id="foo" type="text" />         </div>       </form>     )   } }  const blahpropsadded = addpropsifhoc(node => node.type === 'input')   const blah = blahpropsadded(blahdumb);    // app component class app extends react.purecomponent {   render() {     return (           <div classname="app">             <blah />           </div>     )   } }  // render reactdom.render(<app />, document.getelementbyid('app')) 

here working - https://codesandbox.io/s/6y1lrn7yww

here demo adds props <field> children: https://codesandbox.io/s/9zp9207nvy


Comments

Popular posts from this blog

What is happening when Matlab is starting a "parallel pool"? -

angular - DownloadURL return null in below code -

php - Cannot override Laravel Spark authentication with own implementation -