Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suspense: not yet implemented #22615

Closed
3 tasks done
kevinwolfcr opened this issue Dec 12, 2018 · 10 comments
Closed
3 tasks done

Suspense: not yet implemented #22615

kevinwolfcr opened this issue Dec 12, 2018 · 10 comments
Labels
Bug React Resolution: Locked This issue was locked by the bot.

Comments

@kevinwolfcr
Copy link

kevinwolfcr commented Dec 12, 2018

Environment

[skip envinfo]

{
  "private": true,
  "main": "./app-entry.js",
  "scripts": {
    "dev": "expo start",
    "prod": "expo start --no-dev"
  },
  "dependencies": {
    "expo": "^31.0.2",
    "react": "^16.7.0-alpha.2",
    "react-cache": "^2.0.0-alpha.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-31-with-hooks-dangerzone.tar.gz"
  },
  "devDependencies": {
    "babel-preset-expo": "^5.0.0",
    "expo-cli": "^2.6.12"
  }
}

Description

When trying to use Suspense on React Native, I am receiving a Not yet implemented issue, after the react-cache package has resolved the data.

Reproducible Demo

import React, { useState, ConcurrentMode, Suspense } from "react";
import { StyleSheet, SafeAreaView, Button, Text } from "react-native";
import { unstable_createResource as createResource } from "react-cache";

const myPokemon = createResource(function fetchPokemon(name) {
  const pokemonQuery = `
      query ($name: String) {
        pokemon(name: $name) {
          id
          number
          name
        }
      }
    `;

  return fetch("https://graphql-pokemon.now.sh", {
    method: "POST",
    headers: {
      "content-type": "application/json;charset=UTF-8"
    },
    body: JSON.stringify({
      query: pokemonQuery,
      variables: { name }
    })
  })
    .then(r => r.json())
    .then(response => response.data.pokemon);
});

function PokemonInfo({ pokemonName }) {
  const pokemon = myPokemon.read(pokemonName);
  console.log(pokemon);

  return <Text>{JSON.stringify(pokemon || "Unknown", null, 2)}</Text>;
}

export default function App() {
  const [pokemonName, setPokemonName] = useState(null);
  const [search, setSearch] = useState(false);

  return (
    <SafeAreaView style={styles.container}>
      <Button title="Get Pikachu" onPress={() => setPokemonName("Pikachu")} />
      {pokemonName ? (
        <Suspense fallback={<Text>loading...</Text>}>
          <PokemonInfo pokemonName={pokemonName} />
        </Suspense>
      ) : null}
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: "#fff",
    flex: 1,
    margin: 20
  },
  textInput: {
    backgroundColor: "#eaeaea",
    borderColor: "#cccccc",
    borderWidth: 1,
    height: 40,
    padding: 10
  }
});
@react-native-bot
Copy link
Collaborator

Can you run react-native info and edit your issue to include these results under the Environment section?

If you believe this information is irrelevant to the reported issue, you may write [skip envinfo] under Environment to let us know.

@Taylor123
Copy link
Contributor

Haven't used Suspense yet, but based off the docs it looks like you need to use it with React.lazy

https://reactjs.org/docs/react-api.html#reactsuspense

Today, lazy loading components is the only use case supported by <React.Suspense>

@kevinwolfcr
Copy link
Author

@Taylor123 not necessary, you can use Suspense not to lazy load components, but for suspending rendering when for example, making a http request.

@m-alikhizar
Copy link

m-alikhizar commented Dec 20, 2018

Yes, @Taylor123 we can use react suspense functionality without react.lazy as far as in the context of web. now trying to use in react-native to which i'm facing the same issue.

@Eyesonly88
Copy link
Contributor

Any idea if this is on the roadmap / coming any time soon?

@stvkoch
Copy link

stvkoch commented Mar 1, 2019

It's working in progress, I think that soon will be stable.

function unhideInstance(instance, props) {

Thank you React-Native Team!

@Harag
Copy link

Harag commented Mar 5, 2019

I got the reproduceable demo above (minus the react-cache - did my own test cache) to work in 0.59.0-rc.3.

@stvkoch
Copy link

stvkoch commented Mar 6, 2019

It's working in progress, I think that soon will be stable.

react-native/Libraries/Renderer/oss/ReactNativeRenderer-dev.js

Line 4319 in d4ce846

function unhideInstance(instance, props) {
Thank you React-Native Team!

I'm using this implementation to test my apps, and so far I could go it's working well. I'm found some troubles with expo integration.

Note: 0.59-rc was shipped with support to hooks

@rickhanlonii
Copy link
Member

This should be working in the latest release - if it's not please let us know and we can re-open

@tonmanayo
Copy link

Hi, I'm using react-native 0.59.5 and tried to implement Suspense but it never falls back to the fallback component
ProductsList.js

function ProductsList() {
  const { navigate } = useNavigation()
  const mobileNumber = useNavigationParam("mobileNumber")
  const [departmentData, departmentFetching, departmentError] = useRequest(() =>
    webApi.api.getCallBackDepartments()
  )
  const rows = getRows({ departments: departmentData ? departmentData : [] })

  const handleButtonPress = department => {
    navigate("SelectCallBackTimeScreen", {
      mobileNumber: mobileNumber,
      department: department
    })
  }

  console.log("departmentData", !departmentData.length)
  if (!departmentData.length) {
    return null
  }

  return (
    <View style={{ paddingHorizontal: 10, flex: 1 }}>
      {rows.map(value => (
        <View
          key={shortid.generate()}
          style={[styles.bodyCardRow, { marginTop: -10, marginBottom: 10 }]}
        >
          <View style={styles.bodyCardColumn}>
            <Card
              handlePress={() => handleButtonPress(departmentData[2 * value])}
              name={departmentData[2 * value] ? departmentData[2 * value].name : "test"}
            />
          </View>
          {departmentData[2 + 2 * value] && (
            <Card
              handlePress={() => handleButtonPress(departmentData[1 + 2 * value])}
              name={departmentData[1 + 2 * value] && departmentData[1 + 2 * value].name}
            />
          )}
        </View>
      ))}
    </View>
  )
}

selectAproduct.js

import React, { useEffect, Suspense, lazy } from "react"
import { connect } from "react-redux"
import { BackHandler, SafeAreaView, View } from "react-native"

import { useNavigation } from "react-navigation-hooks"
import BaseStyles from "../../Styles/App"
import CustomHeader from "../../../Components/CustomHeader"
import GoBack from "../../../Components/GoBack"
import Loader from "../../../Components/Loader"
import Text from "../../../Components/Text"
const ProductsLazy = lazy(() => import("./ProductsList"))

function SelectAProduct() {
  const { pop } = useNavigation()

  useEffect(() => {
    const backPressed = () => {
      pop()
      return true
    }
    BackHandler.addEventListener("hardwareBackPress", backPressed)
    return () => {
      BackHandler.removeEventListener("hardwareBackPress", backPressed)
    }
  }, [pop])

  return (
    <View style={BaseStyles.applicationView}>
      <CustomHeader
        popBack={() => pop()}
        left={<GoBack backScreen={"Call Me Back"} />}
        heading={"Select a Product"}
      />
      <Suspense fallback={<Text>loading ...</Text>}>
        <ProductsLazy />
      </Suspense>
      <SafeAreaView />
    </View>
  )
}

function Loading({ departmentFetching }) {
  return (
    <View style={BaseStyles.applicationView}>
      <Loader animating={departmentFetching} />
    </View>
  )
}

const mapStateToProps = state => ({
  // cart: state.cart.items
})

export default connect(
  mapStateToProps,
  {}
)(SelectAProduct)

@facebook facebook locked as resolved and limited conversation to collaborators Mar 19, 2020
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Mar 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug React Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

10 participants