The first two attempts at the end of the question do not work because they rely on the shell splitting the output of jq on whitespace. Since newline is one type of whitespace, you lose the newlines (and tabs and the original spaces) in the data.
The attempts additionally fail to quote the string data, so you would get filename globbing happening if any string contained filename globbing characters.
The last attempt fails for similar reasons but additionally does not properly decode the data, leaving encoded newlines in place.
Using the built-in @sh operator in jq to quote the data and build an array assignment:
eval "$( jq -r '"fruits=(" + (map(.name)|@sh) + ")"' fruits.json )"
For the given JSON data, this would cause the following assignment to be evaluated by the current shell, creating the array fruits:
fruits=('apple' 'banana fofanna' 'my kiwi')
After evaluating that statement,
$ printf '<%s>\n' "${fruits[@]}" <apple> <banana fofanna> <my kiwi>
As an alternative, the following would append each name element's value to the shell array:
$ jq -r '"fruits+=(" + (.[].name | @sh) + ")"' fruits.json fruits+=('apple') fruits+=('banana fofanna') fruits+=('my kiwi')
$ unset -v fruits $ eval "$(jq -r '"fruits+=(" + (.[].name | @sh) + ")"' fruits.json)"
$ printf '<%s>\n' "${fruits[@]}" <apple> <banana fofanna> <my kiwi>