react-hook-form / react-hook-form

📋 React Hooks for form state management and validation (Web + React Native)
https://react-hook-form.com
MIT License
41.58k stars 2.08k forks source link

useFieldArray: TypeError: data.slice is not a function or its return value is not iterable #1450

Closed Bharateshwar closed 4 years ago

Bharateshwar commented 4 years ago

useFieldArray's remove method throws TypeError: data.slice is not a function error. I am using material-ui's textfield with Controller.

To Reproduce Steps to reproduce the behavior:

  1. Go to 'https://codesandbox.io/s/eager-williams-npt2q'
  2. Click on '"Delete Textfield" on the output tab'
  3. See error

Additional context I found many other similar issues but none mentioned using controller .... all the solutions mentioned using register() but I don't see a way for me to use it with controller.

Thanks.

bluebill1049 commented 4 years ago

Try to follow this example with Controller: https://codesandbox.io/s/react-hook-form-usefieldarray-wqyji?file=/src/index.js:995-1027

i have made yours worked as well, but it's better for you to learn and see the diff.

bluebill1049 commented 4 years ago

hint: append API

Type:

const append = (
    value: Partial<FormArrayValues> | Partial<FormArrayValues>[],
)
Bharateshwar commented 4 years ago

hi @bluebill1049 ... i tried but I'm unable to find out what is wrong :(

bluebill1049 commented 4 years ago

here is a working version for you: https://codesandbox.io/s/fervent-moon-ewy1i?file=/src/App.js

append need to be supplied with an object or an array of objects, it wouldn't work with empty.

Bharateshwar commented 4 years ago

thanks @bluebill1049 ...thanks a lot for your help. I even had a silly spelling mistake in my variables ..

Solved it... thanks

caiorios commented 4 years ago

Hello. I had this exactly problem. The issue with this is that the name passed to the hook is different from the one used in the field's name. At the hook, you pass the name prop as ServceProviderAddress, however in your field's name you are using ServiceProviderAddress[$ {index}].

I think it's the case of explain that at the docs.

bluebill1049 commented 4 years ago

@caiorios thanks, let me know how could I improve that section as well, or PR welcome as well.

caiorios commented 4 years ago

I think making a small change in the code at the docs would be enough:

const fieldArrayName = 'test';

const { fields, append, prepend, remove } = useFieldArray({
    control,
    name: fieldArrayName
  });

...
<input name={`${fieldArrayName}[${index}].name`} defaultValue={item.name} ref={register()} />
...
eyalw commented 4 years ago

This is still happening for field arrays that are not binded: Example: https://codesandbox.io/s/loving-goldberg-ev7ig

bluebill1049 commented 4 years ago

This is still happening for field arrays that are not binded: Example: https://codesandbox.io/s/loving-goldberg-ev7ig

That's expected behavior. we don't support custom register with useFieldArray.

eyalw commented 4 years ago

@bluebill1049 but look closely, I'm not using the Controller. I commented it out. I'm using nothing. just rendering the array, with simple text in DOM instead of a field. This is a scenario that I have in my app. And the app crashes on delete.

bluebill1049 commented 4 years ago

Like I mentioned above we don't support custom register (virtual input) for useFieldArray. you should consider use the input type hidden.

cpprookie commented 4 years ago

Like I mentioned above we don't support custom register (virtual input) for useFieldArray. you should consider use the input type hidden.

Try this https://codesandbox.io/s/react-form-hook-bug-ilgv7?file=/src/App.js. After Appended twice, remove one by one will report error "data.slice is not a function or its return value is not iterable", Is there something wrong?

bluebill1049 commented 4 years ago

https://codesandbox.io/s/react-form-hook-bug-ilgv7?file=/src/App.js

hey @cpprookie this should be an easy one: ref={register()}

Screen Shot 2020-07-02 at 8 59 49 pm
cpprookie commented 4 years ago

https://codesandbox.io/s/react-form-hook-bug-ilgv7?file=/src/App.js

hey @cpprookie this should be an easy one: ref={register()}

Screen Shot 2020-07-02 at 8 59 49 pm

ooops! Thanks for your quick reply.Finally I found it in useFieldArray . And i think comment this tip in FieldArrays-usage may be clearer because developer will read it as first entry. Just comment like

<ul>
    {fields.map((item, index) => (
        <li key={item.id}>
            {/* important: useFieldArray only works with ref={register()} */}
            <input name={`test[${index}].name`} defaultValue={item.name} ref={register()} />
            <button onClick={() => remove(index)}>Delete</button>
        </li>
     ))}
</ul>
bluebill1049 commented 4 years ago

send a PR please 🙏 @cpprookie

cpprookie commented 4 years ago

Ok, i will have a try. @bluebill1049