question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

useOfflineMutation

See original GitHub issue

Hello and thanks for the library, I’m trying to achieve offline support using Apollo/GraphQL.

I’ve setup an implementation that looks like the React Native example but whenever I call useOfflineMutation inside my functional component I get the following error:

Screenshot 2020-05-11 at 13 14 29

My code:

import React, {useEffect, useState} from 'react';
import {
  View,
  Text,
  ActivityIndicator,
  FlatList,
  TouchableOpacity,
} from 'react-native';

import {FETCH_TODOS} from '../../graphql/queries/fetchTodos';
import {ADD_TODO} from '../../graphql/queries/addTodo';
import {TOGGLE_TODO} from '../../graphql/queries/toggleTodo';

import {useDarkModeContext} from '../../helpers/DarkMode/context';

import {useQuery} from '@apollo/react-hooks';
import {useOfflineMutation} from 'react-offix-hooks';
import {mutateOptions} from '../../helpers/mutateOptions';

import translations from '../../translations/config';

import styles from './styles';

const HomeScreen = ({navigation}) => {
  const {theme} = useDarkModeContext();
  const {data: remoteData, error, loading} = useQuery(FETCH_TODOS);

  const [addTodo] = useOfflineMutation(
    ADD_TODO,
    mutateOptions(FETCH_TODOS, 'todo', 'add'),
  );

  const [toggleTodo] = useOfflineMutation(
    TOGGLE_TODO,
    mutateOptions(FETCH_TODOS, 'todo', 'refresh'),
  );

  const onCompleteTodo = todoID => {
    toggleTodo({variables: {id: todoID}});
  };

  const renderTodos = ({item}) => {
    return (
      <View style={{marginVertical: 16}}>
        <Text style={{alignSelf: 'center'}}>Title: {item.title}</Text>
        <Text style={{alignSelf: 'center'}}>
          Completed: {item.completed ? 'TRUE' : 'FALSE'}
        </Text>
        {!item.completed && (
          <TouchableOpacity
            style={{alignSelf: 'center', marginVertical: 8}}
            onPress={() => onCompleteTodo(item.id)}>
            <Text>Complete</Text>
          </TouchableOpacity>
        )}
      </View>
    );
  };

  const renderList = () => {
    const {todos} = remoteData;

    return (
      <FlatList
        showsVerticalScrollIndicator={false}
        data={todos}
        renderItem={renderTodos}
        keyExtractor={({id}) => id}
      />
    );
  };

  return (
    <View style={{flex: 1, alignItems: 'center'}}>
      <Text style={styles[theme].title}>{translations.t('home.title')}</Text>
      {remoteData ? renderList() : <ActivityIndicator />}
    </View>
  );
};

export default HomeScreen;

App.js:

import 'react-native-gesture-handler';
import React, {useState, useEffect} from 'react';
import {StatusBar, ActivityIndicator} from 'react-native';
import {NavigationContainer, DefaultTheme} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';
import EStyleSheet from 'react-native-extended-stylesheet';

import {ApolloOfflineProvider} from 'react-offix-hooks';

import HomeScreen from './src/screens/HomeScreen';
import HeaderSwitchTheme from './src/components/ThemeSwitch';

import * as tokens from './src/style-dictionary-dist/variables';

import {
  DarkModeProvider,
  useDarkModeContext,
} from './src/helpers/DarkMode/context';
import {ApolloProvider} from 'react-apollo';
import apolloClientGenerator from './src/graphql/apollo';

const Stack = createStackNavigator();
EStyleSheet.build({});

export default function App() {
  //Change themes for dark mode

  const {theme, changeTheme} = useDarkModeContext();

  const [client, setClient] = useState(null);

  useEffect(() => {
    createApolloClient();
  }, []);

  const createApolloClient = async token => {
    const generatedClient = await apolloClientGenerator(token);
    await generatedClient.init();
    setClient(generatedClient);
  };

  const darkTheme = {
    ...DefaultTheme,
    dark: true,
    colors: {
      ...DefaultTheme.colors,
      primary: tokens.ColorFontInverseBase, //brand color
      background: tokens.ColorBackgroundInverse, //screen background
      card: tokens.ColorBaseGrey900, //header background
      border: tokens.ColorBaseGrey900, //header bottom border
      text: tokens.ColorBaseGrey50, //text color header
    },
  };

  const lightTheme = {
    ...DefaultTheme,
    dark: false,
    colors: {
      ...DefaultTheme.colors,
    },
  };

  const barTheme = {
    dark: 'light-content',
    light: 'dark-content',
  };

  if (!client) {
    return <ActivityIndicator />;
  }

  return (
    <ApolloOfflineProvider client={client}>
      <ApolloProvider client={client}>
        <DarkModeProvider mode={{theme}}>
          <StatusBar barStyle={barTheme[theme]} />
          <NavigationContainer
            theme={theme === 'light' ? lightTheme : darkTheme}>
            <Stack.Navigator>
              <Stack.Screen
                name="Home"
                component={HomeScreen}
                options={{
                  headerRight: () => (
                    <HeaderSwitchTheme
                      selected={theme}
                      onChange={changeTheme}
                    />
                  ),
                }}
              />
            </Stack.Navigator>
          </NavigationContainer>
        </DarkModeProvider>
      </ApolloProvider>
    </ApolloOfflineProvider>
  );
}

My package.json:

 "dependencies": {
    "@apollo/react-hooks": "^3.1.5",
    "@react-native-community/async-storage": "^1.10.0",
    "@react-native-community/masked-view": "^0.1.10",
    "@react-native-community/netinfo": "^5.8.0",
    "@react-navigation/native": "^5.1.7",
    "@react-navigation/stack": "^5.2.14",
    "@tradle/react-native-http": "^2.0.1",
    "apollo-cache-inmemory": "^1.6.5",
    "apollo-cache-persist": "^0.1.1",
    "apollo-client": "^2.6.8",
    "apollo-link": "^1.2.14",
    "apollo-link-http": "^1.5.17",
    "axios": "^0.19.2",
    "graphql": "^15.0.0",
    "graphql-tag": "^2.10.3",
    "i18n-js": "^3.5.1",
    "offix-cache": "^0.15.1",
    "offix-client": "^0.15.1",
    "react": "16.11.0",
    "react-apollo": "^3.1.5",
    "react-native": "0.62.2",
    "react-native-extended-stylesheet": "^0.12.0",
    "react-native-gesture-handler": "^1.6.1",
    "react-native-reanimated": "^1.8.0",
    "react-native-safe-area-context": "^0.7.3",
    "react-native-screens": "^2.7.0",
    "react-offix-hooks": "^0.15.1"
  }

Any help is highly appreciated.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:15 (7 by maintainers)

github_iconTop GitHub Comments

4reactions
KirioXXcommented, May 12, 2020

Hi, we have the same issue after we upgraded to react-native 0.62.2. The recommended react version for 0.62 is v16.11.0, I upgraded the version to v16.13.1 and everything seems to work fine again.

1reaction
KirioXXcommented, May 13, 2020

@dinhmai74 Sure

{
  "name": "mobile",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "android:demo": "ENVFILE=.env.demo react-native run-android --variant=DemoDebug --appIdSuffix=demo",
    "android:prod": "ENVFILE=.env react-native run-android --variant=ProdDebug",
    "android": "ENVFILE=.env.dev react-native run-android --variant=DevDebug --appIdSuffix=test",
    "codegen": "apollo client:codegen -c ./apollo.config.js --target=typescript --globalTypesFile=./App/types/globalTypesFile.ts",
    "ios:demo": "react-native run-ios --scheme \"PatchworkDemo\" --configuration Debug",
    "ios:prod": "react-native run-ios --scheme \"Patchwork\" --configuration Debug",
    "ios": "react-native run-ios --scheme \"PatchworkDev\" --configuration Debug",
    "start": "react-native start",
    "test": "jest -c ./jest.config.js"
  },
  "dependencies": {
    "@gigasz/react-native-sketch-canvas": "0.8.3",
    "@heap/react-native-heap": "0.10.0",
    "@patchwork/config": "1.0.0",
    "@patchwork/library": "1.0.0",
    "@patchwork/resources": "1.0.0",
    "@react-native-community/async-storage": "1.9.0",
    "@react-native-community/masked-view": "0.1.7",
    "@react-native-community/netinfo": "5.8.0",
    "@react-native-community/viewpager": "3.3.0",
    "@react-native-firebase/analytics": "6.4.0",
    "@react-native-firebase/app": "6.4.0",
    "@react-native-firebase/crashlytics": "6.4.0",
    "@react-native-firebase/dynamic-links": "6.4.0",
    "@react-native-firebase/messaging": "6.4.0",
    "@react-native-firebase/perf": "6.4.0",
    "@react-native-firebase/remote-config": "6.4.0",
    "@react-navigation/bottom-tabs": "5.2.6",
    "@react-navigation/native": "5.1.5",
    "@react-navigation/stack": "5.2.10",
    "apollo-cache-inmemory": "1.6.5",
    "apollo-cache-persist": "0.1.1",
    "apollo-client": "2.6.8",
    "apollo-link": "1.2.14",
    "apollo-link-context": "1.0.20",
    "apollo-link-error": "1.1.13",
    "apollo-link-http": "1.5.17",
    "apollo-link-retry": "2.2.16",
    "appcenter": "3.0.2",
    "babel-plugin-transform-remove-console": "6.9.4",
    "color": "3.1.2",
    "expo-document-picker": "8.1.0",
    "expo-file-system": "8.1.0",
    "formik": "2.1.4",
    "fuse.js": "5.1.0",
    "graphql": "15.0.0",
    "graphql-tag": "2.10.3",
    "jwt-decode": "2.2.0",
    "moment": "2.24.0",
    "moment-timezone": "0.5.28",
    "offix-client": "0.15.1",
    "react": "16.13.1",
    "react-apollo": "3.1.4",
    "react-native": "0.62.2",
    "react-native-add-calendar-event": "3.0.2",
    "react-native-calendars": "1.265.0",
    "react-native-config": "1.0.0",
    "react-native-device-info": "5.5.4",
    "react-native-easy-content-loader": "0.3.2",
    "react-native-email-link": "1.7.3",
    "react-native-fast-image": "8.1.5",
    "react-native-gesture-handler": "1.6.1",
    "react-native-image-picker": "2.3.1",
    "react-native-intercom": "14.0.0",
    "react-native-keyboard-aware-scroll-view": "0.9.1",
    "react-native-location": "2.5.0",
    "react-native-reanimated": "1.8.0",
    "react-native-safe-area-context": "0.7.3",
    "react-native-screens": "2.4.0",
    "react-native-share": "3.2.0",
    "react-native-splash-screen": "3.2.0",
    "react-native-svg": "12.1.0",
    "react-native-unimodules": "0.9.0",
    "react-native-version-number": "0.3.6",
    "react-offix-hooks": "0.15.1",
    "remove": "0.1.5",
    "rn-secure-storage": "2.0.4",
    "rollbar-react-native": "0.7.2",
    "url": "0.11.0",
    "waait": "1.0.5",
    "yup": "0.28.3"
  },
  "devDependencies": {
    "reactotron-react-native": "5.0.0"
  },
  "workspaces": {
    "nohoist": [
      "**"
    ]
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

React - using Offix Hooks
useOfflineMutation is similar to useMutation but it internally calls client.offlineMutate . useOfflineMutation will throw an offline error if the mutation was ...
Read more >
React-offix-hooks NPM | npm.io
react-offix-hooks · API · OffixProvider · Usage With react-apollo-hooks · useOfflineMutation.
Read more >
Mutations in Apollo Client - Apollo GraphQL Docs
The useMutation React hook is the primary API for executing mutations in an Apollo application. To execute a mutation, you first call useMutation...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found