facebookexperimental / Recoil

Recoil is an experimental state management library for React apps. It provides several capabilities that are difficult to achieve with React alone, while being compatible with the newest features of React.
https://recoiljs.org/
MIT License
19.6k stars 1.19k forks source link

React Native, Expo support? Throw Error: "s" is read-only #38

Closed igsys closed 4 years ago

igsys commented 4 years ago

Nice library! I am using this in an Expo project (SDK37), it gives me _readOnlyError. I thought I did something wrong with my code, and used the example from document, and output the same errors when I use 'selector' as an argument in useRecoilState. Notice, 'atom' does not throw errors, working fine.

Any solution to this?

import {
  Text,
  Button,
  View,
} from 'react-native'
import { atom, selector, useRecoilState } from 'recoil'

const tempFahrenheit = atom({
  key: 'tempFahrenheit',
  default: 32,
})

const tempCelcius = selector({
  key: 'tempCelcius',
  get: ({ get }) => ((get(tempFahrenheit) - 32) * 5) / 9,
  set: ({ set }, newValue) => set(tempFahrenheit, (newValue * 9) / 5 + 32),
})

const TempCelcius = () => {
  const [tempF, setTempF] = useRecoilState(tempFahrenheit)
  const [tempC, setTempC] = useRecoilState(tempCelcius)

  const addTenCelcius = () => setTempC(tempC + 10)
  const addTenFahrenheit = () => setTempF(tempF + 10)

  return (
    <View>
      <Text>Temp (Celcius): {tempC}</Text>
      <Text>Text>Temp (Fahrenheit): {tempF}</Text>
      <Button
        title='Add 10 Celcius'
        onPress={addTenCelcius} />
      <Button
        title='Add 10 Fahrenheit'
        onPress={addTenFahrenheit}
      />
    </View>
  )
}

export {
  TempCelcius,
}
export default TempCelcius

Error

Error: "s" is read-only

_readOnlyError
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:147369:20
c
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:147190:42
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:147195:24
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:147216:10
i
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:147250:8
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:146334:21
replaceState
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:146567:20
getRecoilValueAsLoadable
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:146332:21
r
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:146808:12
getRecoilState
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:146815:20
useRecoilState
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:146905:47
renderWithHooks
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:20048:33
mountIndeterminateComponent
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:22097:34
beginWork$$1
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:27288:31
performUnitOfWork
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:26441:30
workLoopSync
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:26423:45
renderRoot
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:26187:29
renderRoot
    [native code]:0
runRootCallback
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:25948:34
runRootCallback
    [native code]:0
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:16678:38
unstable_runWithPriority
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:43144:30
flushSyncCallbackQueueImpl
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:16673:28
flushSyncCallbackQueue
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:16662:35
scheduleUpdateOnFiber
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:25830:37
scheduleRootUpdate
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:28255:21
scheduleRoot
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:17226:42
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:41547:35
forEach
    [native code]:0
performReactRefresh
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:41539:30
performReactRefresh
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:41345:48
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:480:40
_callTimer
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:31051:17
callTimers
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:31258:19
__callFunction
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:3225:49
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:2938:31
__guard
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:3179:15
callFunctionReturnFlushedQueue
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:2937:21
callFunctionReturnFlushedQueue
    [native code]:0
suhaotian commented 4 years ago

The hooks write with react-dom, https://github.com/facebookexperimental/Recoil/blob/master/src/hooks/Recoil_Hooks.js#L24

That means the library didn't support react-native yet

ghidoras commented 4 years ago

hm. I somehow have this error in a web app, not react-native.

ghidoras commented 4 years ago

in my case the selector fails on get(manuscriptAtom);

export const journalNameAtom = selector({
  key: 'journalName',
  get({ get }) {
    const manuscript: Manuscript = get(manuscriptAtom);
    return manuscript?.journal?.name ?? '';
  },
});

tried to get rid of

alias: {
  'react-dom': '@hot-loader/react-dom',
},

from webpack config and still nothing. Using version 0.0.7

ralphievolt commented 4 years ago

same error here in react-native... i wonder how difficult is it to implement in react native

Naturalclar commented 4 years ago

I'm thinking if somehow we can replace the usage of react-dom with react-reconciler, we can use recoil with react-native projects. I've looked at it a little, but it doesn't seem like a simple replacement that can be done with codemod. I'd have to look into it further.

Robert187 commented 4 years ago

Yeah I have that same problem on one my phone s

Robert187 commented 4 years ago

I'll have to look into it I can revoke it butt Im not sure if you want that

jacques-blom commented 4 years ago

It's working for me when I link it locally and build it without terser (minification). Here's my Expo project if anyone wants to see how to get linking working: https://github.com/jacques-blom/recoil-test-expo

Check out the Readme for setup instructions.

Looking into why terser is causing this.

jacques-blom commented 4 years ago
jacques-blom commented 4 years ago

Here's a PR that aims to fix this: https://github.com/facebookexperimental/Recoil/pull/69

davidmccabe commented 4 years ago

Thanks for reporting and for the fix!