Reputation: 2105
I have an expo project that I want to use hooks in.
I get the following error upon starting my app:
TypeError: dispatcher.useState is not a function. (In 'dispatcher.useState(initialState)', 'dispatcher.useState' is undefined)
As per the advice in another well referenced issue, I've updated my package.json to include:
"react": "16.7.0-alpha.2",
but got the same error. Thanks for any help.
Edit: Removed dependency on react-dom as pointed out by Boy With Silver Wings.
Upvotes: 1
Views: 2113
Reputation: 2105
Following this, I made a script for how to fix it. Just define $MY_NODE_PROJECT_DIR
:
git clone https://github.com/facebook/react
cd react
# files that need to be modified found with grep -lr 'enableHooks = false'
# packages/shared/ReactFeatureFlags.js
# packages/shared/forks/ReactFeatureFlags.test-renderer.js
# packages/shared/forks/ReactFeatureFlags.native-oss.js
# packages/shared/forks/ReactFeatureFlags.persistent.js
# replace enableHooks false with true
grep -lr 'enableHooks = false' | xargs sed -i 's/enableHooks = false/enableHooks = true/g'
yarn install
# this requires JAVA is on your path
# install with `apt install default-jdk`
yarn build -- --type=RN_OSS
# copy the built files into our renderer
cp -R build/react-native/* $MY_NODE_PROJECT_DIR/node_modules/react-native/Libraries/Renderer
As per the comment, I removed the unnecessary dependencies from my package.json giving the following (with a few dependencies specific to my project):
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject",
"test": "node ./node_modules/jest/bin/jest.js --watchAll"
},
"jest": {
"preset": "jest-expo"
},
"dependencies": {
"@expo/samples": "2.1.1",
"aws-amplify": "^1.1.12",
"aws-amplify-react-native": "^2.0.10",
"expo": "^31.0.2",
"react": "16.7.0-alpha.2",
"react-native": "https://github.com/expo/react-native/archive/sdk-31.0.0.tar.gz",
"react-native-easy-grid": "0.2.0",
"react-native-swipe-gestures": "1.0.3",
"react-navigation": "^2.18.2"
},
"devDependencies": {
"@babel/runtime": "7.0.0",
"@types/react": "^16.7.17",
"@types/react-native": "^0.57.18",
"babel-preset-expo": "^5.0.0",
"jest-expo": "^31.0.0",
"react-native-typescript-transformer": "^1.2.10",
"schedule": "^0.4.0",
"typescript": "^3.2.2"
},
"private": true
}
Then run your application as normal. Here's an example app to test that it has worked:
import React, { useState } from 'react';
import { StyleSheet, Text, View } from 'react-native';
function Counter() {
let [count, setCount] = useState(0);
return <Text onPress={() => setCount(count + 1)}>{count}</Text>;
}
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<Counter />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
What mine looks like after:
Upvotes: 2