7

I am using material ui ExpansionPanel. I am trying to add new panels from Add button click and remove panel from Remove button click, its working fine, problem is, when i expand, collapse, add or remove panels, form fields value get lost. I think it happens due to re-rendering or refresh.

Let me know how can we implement above feature so that user can easly navigate to any panel add some detail from there and move to another panel and add some detail there, but while adding details from one to another panel, value must be there if user again goes to that perticular panel.

Have a look on below sample code

https://codesandbox.io/s/dhananajayx-3n73x?file=/src/App.js:146-160

Any effort is highly appreciated

5 Answers5

6

useForm({ shouldUnregister: false });

When working with react-hook-form and each form element is rendered on a tab change or so, use the above code to not let any field unregister from the form and keep the form values as it is.

0
  1. Send a ref to component(read Register fields for more information)
  2. Set the defaultValue with previous value. in each re-render component uses default value in its input.

look at this at codesandbox.

Bonje Fir
  • 787
  • 8
  • 25
0

React Hook Form automatically removes value when input removes from the DOM tree, basically unregister is invoked when your inputs get collapsed.

Solution

useEffect(() => {
  register('yourInput');
}, [register])


setValue('yourInput', 'data')

This unregister will not happen automatically and you can drive when to invoke unregister.

Bill
  • 17,872
  • 19
  • 83
  • 131
  • 1
    Does this mean that if I have a panel with 20 inputs in it that renders conditionally, do I need to register each of them independently? Or is there a cleaner method of doing this? – Jarrod McGuire Feb 19 '21 at 15:30
0

This works:

In the Main view:

const methods = useForm(form)
const [value, setValue] = useState(0)

<FormProvider {...{value, ...methods}}>

</FormProvider>

Example Tab Items:

// first item 
const TabItem1 = () => {
    const {value} = useFormContext()

    return <TabPanel {...{value, index: 0}}>
      {/*{Content here}*/}
    </TabPanel>
}

export default TabItem1

// second item
const TabItem2 = () => {
    const {value} = useFormContext()

    return <TabPanel {...{value, index: 1}}>
      {/*{content here}*/}
    </TabPanel>
}

export default TabItem2

And the TabPanel:

const TabPanel = ({children, value, index}) =>
    <div style={{display: value === index ? 'block' : 'none'}}>
        {children}
    </div>

export default TabPanel
francis
  • 3,852
  • 1
  • 28
  • 30
0

I use stepper to enter user info divided to 4 steps & useForm({ shouldUnregister: false }); didn't work so I Changed this:

 {activeStep === 0 && (
            <label>
              Name:
              <input type="text" name="name"  />
            </label>
          )}

to:

 <label>
            Name:
            <input
              type="text"
              name="name"
              style={{ display: activeStep === 0 ? "block" : "none" }}
            />
 </label>
Abdelrahman Tareq
  • 1,874
  • 3
  • 17
  • 32