Update all react children components












1















I have a code like this:



<Editor source="/api/customer" onCreate={this.debugChange} onDelete={this.debugChange} onUpdate={this.debugChange}>
<Group title="Address">
<Column id="id" label="ID" default={0} readonly />
<Column id="name" label="name" default="" />
<Column id="address" label="Address" default="" />
<Column id="country" label="Country" default={currentCountry} readonly source="/api/country" idfield="id" captionField="name" />
</Group>
<Group title="Payment">
<Column id="tax" label="TaxType" default={0} source="/api/taxtype" idfield="id" captionField="name" />
<Column id="bank" label="Bank" default="" source="/api/banks" idfield="id" captionField="bank"/>
<Column id="account" label="Account Number" default="" />
</Group>
</Editor>


Editor has a render() function like this:



    let components = React.Children.map(this.props.children, (child) => {
return <Column {...child.props} default={row[child.props.id]} onChange={this.onChange.bind(this)} />
})

return <div className="hx-editor">
<div className="hx-editor-list">
<List id={this.props.id + "-list"} source={this.props.source}
singleShow captionField={this.caption.bind(this)}
groupfn={this.props.group} onSelect={this.onSelect.bind(this)} />
</div>
<form name={"hx-form-" + this.props.id} className="hx-form">
{components}
{buttons}
</form>
</div >


I have the function like this at <List>'s onSelect



private onSelect(id: string, data: T) {
this.setState({
currentRow: data,
modifiedRow: data
})
}


<Editor> will show a list from /api/customer with <List>, and send the selected values to onSelect props, which in turn update all <Column> children. The data corresponds with column's id, such as:



data = [{
id: 0,
name: 'My Customer',
address: 'This is Address',
country: 'US',
tax: '010',
bank: 'HSBC',
account:: '89238882839304'
}, ... ]


This method that I put here, only works with children directly under <Editor>, but not under <Group>.



My question is, how can I do deep update of all values of <Column> as <Editor>'s children when a user clicked on a value in <List>. I mean, perform <Column> search through all children, and update all values, no matter where they are, as long as within <Editor> tag.



Any help is appreciated. Thank you










share|improve this question

























  • Nothing changed in <Group /> - no reason to rerender

    – xadm
    Nov 25 '18 at 14:26











  • I want to change <Column /> inside <Group />

    – Magician
    Nov 25 '18 at 16:09
















1















I have a code like this:



<Editor source="/api/customer" onCreate={this.debugChange} onDelete={this.debugChange} onUpdate={this.debugChange}>
<Group title="Address">
<Column id="id" label="ID" default={0} readonly />
<Column id="name" label="name" default="" />
<Column id="address" label="Address" default="" />
<Column id="country" label="Country" default={currentCountry} readonly source="/api/country" idfield="id" captionField="name" />
</Group>
<Group title="Payment">
<Column id="tax" label="TaxType" default={0} source="/api/taxtype" idfield="id" captionField="name" />
<Column id="bank" label="Bank" default="" source="/api/banks" idfield="id" captionField="bank"/>
<Column id="account" label="Account Number" default="" />
</Group>
</Editor>


Editor has a render() function like this:



    let components = React.Children.map(this.props.children, (child) => {
return <Column {...child.props} default={row[child.props.id]} onChange={this.onChange.bind(this)} />
})

return <div className="hx-editor">
<div className="hx-editor-list">
<List id={this.props.id + "-list"} source={this.props.source}
singleShow captionField={this.caption.bind(this)}
groupfn={this.props.group} onSelect={this.onSelect.bind(this)} />
</div>
<form name={"hx-form-" + this.props.id} className="hx-form">
{components}
{buttons}
</form>
</div >


I have the function like this at <List>'s onSelect



private onSelect(id: string, data: T) {
this.setState({
currentRow: data,
modifiedRow: data
})
}


<Editor> will show a list from /api/customer with <List>, and send the selected values to onSelect props, which in turn update all <Column> children. The data corresponds with column's id, such as:



data = [{
id: 0,
name: 'My Customer',
address: 'This is Address',
country: 'US',
tax: '010',
bank: 'HSBC',
account:: '89238882839304'
}, ... ]


This method that I put here, only works with children directly under <Editor>, but not under <Group>.



My question is, how can I do deep update of all values of <Column> as <Editor>'s children when a user clicked on a value in <List>. I mean, perform <Column> search through all children, and update all values, no matter where they are, as long as within <Editor> tag.



Any help is appreciated. Thank you










share|improve this question

























  • Nothing changed in <Group /> - no reason to rerender

    – xadm
    Nov 25 '18 at 14:26











  • I want to change <Column /> inside <Group />

    – Magician
    Nov 25 '18 at 16:09














1












1








1








I have a code like this:



<Editor source="/api/customer" onCreate={this.debugChange} onDelete={this.debugChange} onUpdate={this.debugChange}>
<Group title="Address">
<Column id="id" label="ID" default={0} readonly />
<Column id="name" label="name" default="" />
<Column id="address" label="Address" default="" />
<Column id="country" label="Country" default={currentCountry} readonly source="/api/country" idfield="id" captionField="name" />
</Group>
<Group title="Payment">
<Column id="tax" label="TaxType" default={0} source="/api/taxtype" idfield="id" captionField="name" />
<Column id="bank" label="Bank" default="" source="/api/banks" idfield="id" captionField="bank"/>
<Column id="account" label="Account Number" default="" />
</Group>
</Editor>


Editor has a render() function like this:



    let components = React.Children.map(this.props.children, (child) => {
return <Column {...child.props} default={row[child.props.id]} onChange={this.onChange.bind(this)} />
})

return <div className="hx-editor">
<div className="hx-editor-list">
<List id={this.props.id + "-list"} source={this.props.source}
singleShow captionField={this.caption.bind(this)}
groupfn={this.props.group} onSelect={this.onSelect.bind(this)} />
</div>
<form name={"hx-form-" + this.props.id} className="hx-form">
{components}
{buttons}
</form>
</div >


I have the function like this at <List>'s onSelect



private onSelect(id: string, data: T) {
this.setState({
currentRow: data,
modifiedRow: data
})
}


<Editor> will show a list from /api/customer with <List>, and send the selected values to onSelect props, which in turn update all <Column> children. The data corresponds with column's id, such as:



data = [{
id: 0,
name: 'My Customer',
address: 'This is Address',
country: 'US',
tax: '010',
bank: 'HSBC',
account:: '89238882839304'
}, ... ]


This method that I put here, only works with children directly under <Editor>, but not under <Group>.



My question is, how can I do deep update of all values of <Column> as <Editor>'s children when a user clicked on a value in <List>. I mean, perform <Column> search through all children, and update all values, no matter where they are, as long as within <Editor> tag.



Any help is appreciated. Thank you










share|improve this question
















I have a code like this:



<Editor source="/api/customer" onCreate={this.debugChange} onDelete={this.debugChange} onUpdate={this.debugChange}>
<Group title="Address">
<Column id="id" label="ID" default={0} readonly />
<Column id="name" label="name" default="" />
<Column id="address" label="Address" default="" />
<Column id="country" label="Country" default={currentCountry} readonly source="/api/country" idfield="id" captionField="name" />
</Group>
<Group title="Payment">
<Column id="tax" label="TaxType" default={0} source="/api/taxtype" idfield="id" captionField="name" />
<Column id="bank" label="Bank" default="" source="/api/banks" idfield="id" captionField="bank"/>
<Column id="account" label="Account Number" default="" />
</Group>
</Editor>


Editor has a render() function like this:



    let components = React.Children.map(this.props.children, (child) => {
return <Column {...child.props} default={row[child.props.id]} onChange={this.onChange.bind(this)} />
})

return <div className="hx-editor">
<div className="hx-editor-list">
<List id={this.props.id + "-list"} source={this.props.source}
singleShow captionField={this.caption.bind(this)}
groupfn={this.props.group} onSelect={this.onSelect.bind(this)} />
</div>
<form name={"hx-form-" + this.props.id} className="hx-form">
{components}
{buttons}
</form>
</div >


I have the function like this at <List>'s onSelect



private onSelect(id: string, data: T) {
this.setState({
currentRow: data,
modifiedRow: data
})
}


<Editor> will show a list from /api/customer with <List>, and send the selected values to onSelect props, which in turn update all <Column> children. The data corresponds with column's id, such as:



data = [{
id: 0,
name: 'My Customer',
address: 'This is Address',
country: 'US',
tax: '010',
bank: 'HSBC',
account:: '89238882839304'
}, ... ]


This method that I put here, only works with children directly under <Editor>, but not under <Group>.



My question is, how can I do deep update of all values of <Column> as <Editor>'s children when a user clicked on a value in <List>. I mean, perform <Column> search through all children, and update all values, no matter where they are, as long as within <Editor> tag.



Any help is appreciated. Thank you







reactjs typescript3.0






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 26 '18 at 8:00







Magician

















asked Nov 25 '18 at 14:05









MagicianMagician

5763928




5763928













  • Nothing changed in <Group /> - no reason to rerender

    – xadm
    Nov 25 '18 at 14:26











  • I want to change <Column /> inside <Group />

    – Magician
    Nov 25 '18 at 16:09



















  • Nothing changed in <Group /> - no reason to rerender

    – xadm
    Nov 25 '18 at 14:26











  • I want to change <Column /> inside <Group />

    – Magician
    Nov 25 '18 at 16:09

















Nothing changed in <Group /> - no reason to rerender

– xadm
Nov 25 '18 at 14:26





Nothing changed in <Group /> - no reason to rerender

– xadm
Nov 25 '18 at 14:26













I want to change <Column /> inside <Group />

– Magician
Nov 25 '18 at 16:09





I want to change <Column /> inside <Group />

– Magician
Nov 25 '18 at 16:09












2 Answers
2






active

oldest

votes


















0














<Group /> as intermediate 'layer' will 'block change propagation` - this component is not 'consuming' any prop and is therefore not change aware.



You can/need:




  • change structure;

  • pass prop that will be changed (and will force updates in children);

  • use redux;

  • use context API.






share|improve this answer
























  • Well, it is not <Group /> per se, as anything inside <Editor /> will have its <Column /> value managed by editor. So, it can be in any component, like <Tab /> or <Panel /> or any UI layout components or extra components

    – Magician
    Nov 25 '18 at 23:20



















0














Ok... This will break Typescript, I don't know how to type it in Typescript properly, but this one works.



private deepColumn(children: React.ReactNode) => any) {
return React.Children.map(children, child => {
if (child.props.children) {
child = React.cloneElement(child, {
children: this.deepColumn(child.props.children)
})
}
if (child.type.name == "Column") {
return <Column {...child.props} default={this.default} onChange={this.onChange.bind(this)} />
} else return child;
})
}





share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53468301%2fupdate-all-react-children-components%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    <Group /> as intermediate 'layer' will 'block change propagation` - this component is not 'consuming' any prop and is therefore not change aware.



    You can/need:




    • change structure;

    • pass prop that will be changed (and will force updates in children);

    • use redux;

    • use context API.






    share|improve this answer
























    • Well, it is not <Group /> per se, as anything inside <Editor /> will have its <Column /> value managed by editor. So, it can be in any component, like <Tab /> or <Panel /> or any UI layout components or extra components

      – Magician
      Nov 25 '18 at 23:20
















    0














    <Group /> as intermediate 'layer' will 'block change propagation` - this component is not 'consuming' any prop and is therefore not change aware.



    You can/need:




    • change structure;

    • pass prop that will be changed (and will force updates in children);

    • use redux;

    • use context API.






    share|improve this answer
























    • Well, it is not <Group /> per se, as anything inside <Editor /> will have its <Column /> value managed by editor. So, it can be in any component, like <Tab /> or <Panel /> or any UI layout components or extra components

      – Magician
      Nov 25 '18 at 23:20














    0












    0








    0







    <Group /> as intermediate 'layer' will 'block change propagation` - this component is not 'consuming' any prop and is therefore not change aware.



    You can/need:




    • change structure;

    • pass prop that will be changed (and will force updates in children);

    • use redux;

    • use context API.






    share|improve this answer













    <Group /> as intermediate 'layer' will 'block change propagation` - this component is not 'consuming' any prop and is therefore not change aware.



    You can/need:




    • change structure;

    • pass prop that will be changed (and will force updates in children);

    • use redux;

    • use context API.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 25 '18 at 17:50









    xadmxadm

    1,625248




    1,625248













    • Well, it is not <Group /> per se, as anything inside <Editor /> will have its <Column /> value managed by editor. So, it can be in any component, like <Tab /> or <Panel /> or any UI layout components or extra components

      – Magician
      Nov 25 '18 at 23:20



















    • Well, it is not <Group /> per se, as anything inside <Editor /> will have its <Column /> value managed by editor. So, it can be in any component, like <Tab /> or <Panel /> or any UI layout components or extra components

      – Magician
      Nov 25 '18 at 23:20

















    Well, it is not <Group /> per se, as anything inside <Editor /> will have its <Column /> value managed by editor. So, it can be in any component, like <Tab /> or <Panel /> or any UI layout components or extra components

    – Magician
    Nov 25 '18 at 23:20





    Well, it is not <Group /> per se, as anything inside <Editor /> will have its <Column /> value managed by editor. So, it can be in any component, like <Tab /> or <Panel /> or any UI layout components or extra components

    – Magician
    Nov 25 '18 at 23:20













    0














    Ok... This will break Typescript, I don't know how to type it in Typescript properly, but this one works.



    private deepColumn(children: React.ReactNode) => any) {
    return React.Children.map(children, child => {
    if (child.props.children) {
    child = React.cloneElement(child, {
    children: this.deepColumn(child.props.children)
    })
    }
    if (child.type.name == "Column") {
    return <Column {...child.props} default={this.default} onChange={this.onChange.bind(this)} />
    } else return child;
    })
    }





    share|improve this answer






























      0














      Ok... This will break Typescript, I don't know how to type it in Typescript properly, but this one works.



      private deepColumn(children: React.ReactNode) => any) {
      return React.Children.map(children, child => {
      if (child.props.children) {
      child = React.cloneElement(child, {
      children: this.deepColumn(child.props.children)
      })
      }
      if (child.type.name == "Column") {
      return <Column {...child.props} default={this.default} onChange={this.onChange.bind(this)} />
      } else return child;
      })
      }





      share|improve this answer




























        0












        0








        0







        Ok... This will break Typescript, I don't know how to type it in Typescript properly, but this one works.



        private deepColumn(children: React.ReactNode) => any) {
        return React.Children.map(children, child => {
        if (child.props.children) {
        child = React.cloneElement(child, {
        children: this.deepColumn(child.props.children)
        })
        }
        if (child.type.name == "Column") {
        return <Column {...child.props} default={this.default} onChange={this.onChange.bind(this)} />
        } else return child;
        })
        }





        share|improve this answer















        Ok... This will break Typescript, I don't know how to type it in Typescript properly, but this one works.



        private deepColumn(children: React.ReactNode) => any) {
        return React.Children.map(children, child => {
        if (child.props.children) {
        child = React.cloneElement(child, {
        children: this.deepColumn(child.props.children)
        })
        }
        if (child.type.name == "Column") {
        return <Column {...child.props} default={this.default} onChange={this.onChange.bind(this)} />
        } else return child;
        })
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 26 '18 at 8:03

























        answered Nov 25 '18 at 23:13









        MagicianMagician

        5763928




        5763928






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53468301%2fupdate-all-react-children-components%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Wiesbaden

            Marschland

            Dieringhausen