Cannot pass props (state-variable) to Tab-content (re-renders at first change)

Hi,

I'm passing a state-variable to all my tab components as a prop, since I want to prevent the tab-change before the button "Save" is pressed. The state-variable keeps track, if there was an unsaved change.

However, at the first change in the textbox inside the tab-component, which invokes the modification of the state variable, the whole tab gets re-rendered. In other words, when I'm using the prop of the tab-component for the first time, the whole tab-component gets re-rendered. This occurs only at the first usage.


I've attached a demo, that shows the error. Basically, just enter a text in the demo-textbox, and the whole tab-componet gets re-rendered (and the input of the textbox is lost). After the first input the example works... The error happens only at the very-first input.


Thanks.


Attachment: react3ax366_795f389f.zip

3 Replies

SK Satheesh Kumar Balasubramanian Syncfusion Team April 11, 2022 02:16 PM UTC

Hi Laurin,

 

 You can render tab content as separate react component to resolve the reported issue.

 

index.js:    

export const Default = () => {

 

  return (

    <div className="control-pane">

      <div className="control-section tab-control-section">

        <TabComponent selecting={selecting}>

          <TabItemsDirective>

            <TabItemDirective header={{ text: 'Tab 1' }} content={FirstTab} />

            <TabItemDirective header={{ text: 'Tab 2' }} content={tab2} />

          </TabItemsDirective>

        </TabComponent>

      </div>

    </div>

  );

};

 

export const FirstTab = () => {

  const [unsavedChanges, setUnsavedChanges] = React.useState(false);

 

  const input = () => {

    setUnsavedChanges(true);

  };

  return (

    <div>

    <TextBoxComponent placeholder="Value 1" input={input} />

    <ButtonComponent onClick={() => setUnsavedChanges(false)}>

      Save

    </ButtonComponent>

  </div>

  );

};

 

render(<Default />, document.getElementById('sample'));

 

Kindly try the above sample and let us know if this meets your requirement.

 

Regards,

Satheesh Kumar B


Attachment: TabReRender_4a892505.zip


LS Laurin S April 11, 2022 03:30 PM UTC

Thanks for your reply, but this is not the answer for my question.

I know that I can declare the state variable inside the single Tab, but I cannot do that for certain reasons.

An example reason might for example be, that I want to share the "unsavedChanges" variable between various tab's... How can I solve that? This scenario is also shown in my initial demo code...




SK Satheesh Kumar Balasubramanian Syncfusion Team April 12, 2022 01:45 PM UTC

Hi Laurin,

 

You can use the below customization in tab selecting event instead of react useState to resolve the reported issue.


https://www.syncfusion.com/downloads/support/directtrac/general/ze/TabState-1453123063  


index.js:    

export const Default = () => {

  const [unsavedChanges, setUnsavedChanges] = React.useState(false);

  const textbox1 = React.useRef();

  const textbox2 = React.useRef();

  const tab1 = () => {

    return (

      <div>

        <TextBoxComponent ref={textbox1} placeholder="Value 1" />

        <ButtonComponent onClick={() => setUnsavedChanges(false)}>

          Save

        </ButtonComponent>

      </div>

    );

  };

  const tab2 = () => {

    return (

      <div>

        <TextBoxComponent ref={textbox2} placeholder="Value 2" />

        <ButtonComponent onClick={() => setUnsavedChanges(false)}>

          Save

        </ButtonComponent>

      </div>

    );

  };

  const selecting = (args) => {

    if ((isNullOrUndefined(textbox1.current.value) || textbox1.current.value == "") && args.selectingIndex == 1) {

      args.cancel = true;

      alert('Please save your changes first.');

    }

  };

};

 

Could you please check the attached sample and confirm the above solution resolves the problem at your end?

 

Regards,

Satheesh Kumar B


Loader.
Up arrow icon