0

I have a variable that I want to keep track of and update its value between two classes. In one of my classes, I started using props like this with the variable isLoading in my Post class:


class Post extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isLoading: false
        };
    }
    post = () => {
        this.props.uploadPost()
        this.props.updatePhoto()
        this.props.updateDescription('')
        this.props.navigation.navigate('Home')
    }
    openLibrary = async () => {
        const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL)
        if (status === 'granted') {
            const image = await ImagePicker.launchImageLibraryAsync()
            if(!image.cancelled ){
                this.setState({ isLoading: true });

                const resize = await ImageManipulator.manipulateAsync(image.uri, [], { format: 'jpeg', compress: 0.1 })
                const url = await this.props.uploadPhoto(resize.uri) 
                this.props.updatePhoto(url)
                this.setState({ isLoading: false });
            }
        }
    }
...

Now, I also have another class called Camera that I want to update this same variable. However, I'm not implementing a child like function where I call Post or Camera class in each other. This is my code for Camera.


class CameraUpload extends React.Component {    
    state = {
        type: Camera.Constants.Type.back,
    };
    
    snapPhoto = async () => {
        const { status } = await Camera.requestPermissionsAsync();
        if (status === 'granted') {
            const image = await this.camera.takePictureAsync()
            global.config.loading = true;
            image ? this.props.navigation.navigate('Post') : null
            if( !image.cancelled ){
                const resize = await ImageManipulator.manipulateAsync(image.uri, [], { format: 'jpeg', compress: 0.1 })
                const url = await this.props.uploadPhoto(resize.uri)
                this.props.updatePhoto(url)
                loading = false;
                // url ? this.props.navigation.navigate('Post') : null 
            }
        }
    }

I tried using a global config variable but the variable's value was not getting updated between classes. Please let me know what the best way to go about solving this problem is. Thanks!

krish
  • 37
  • 2
  • 10

3 Answers3

0

React Context

You can use the concept of "Context" in react. You may read about it here

https://reactjs.org/docs/context.html

Async Storage

Also you can use async storage if it suits your design

You can make one utility class:

import AsyncStorage from '@react-native-community/async-storage';

export async function storeData(key, value) {
    try {
        await AsyncStorage.setItem(key, value)
    } catch (e) {
        console.log("Error Storing in AsyncStorage stroing " + key + " in async Storage")
    }
}

export async function getData(key) {
    try {
        const value = await AsyncStorage.getItem(key)
        return (value == null || value == undefined) ? undefined : value
    } catch (e) {
        console.log("Error Reading in AsyncStorage stroing " + key + " in async Storage")
    }
}

You can store and get data through key-value pairs.

// Firstly import it in your js

import * as asyncStorage from './AsyncStorage'

//For storingthe data:

 await asyncStorage.storeData("key1", "value1");

// For getting the data:

 await asyncStorage.getData("key1")
Raghvender Kataria
  • 1,457
  • 7
  • 14
  • Lets say I create a context variable called let loading = React.createContext(false); in my post class. I tried just updating the variable in the camera class by setting loading = true in the function but the value did not change. Am I using this correctly? – krish Jun 25 '20 at 05:04
  • No, You can't do it like this. You can have an idea of updating context from here. https://stackoverflow.com/a/50502829/10720296 – Raghvender Kataria Jun 25 '20 at 05:25
  • I have edited my answer and shown the other method as well where you can use async storage to store and get data – Raghvender Kataria Jun 25 '20 at 05:58
0

You can try global variable:

class post {

   onpost(){
      global.isLoading = true;
  }
}


class cameraupload {
   componentDidMount(){
      global.isLoading = false;
   }
}
Khurshid Ansari
  • 4,638
  • 2
  • 33
  • 52
0

Context is the way to go for small pieces of shared state, in my opinion.

Combined with hooks, it's very easy to access state and call functions from any child component.

Define your provider with any shared state and functions

import React, { createContext, useState } from 'react'

const Context = createContext()

const MySharedStateProvider = ({ children }) => {
  const [myState, setMyState] = useState('hello')

  const updateMyState = value => setMyState(value)

  return (
    <Context.Provider value={{ myState, updateMyState }}>
      {children}
    </Context.Provider>
  )
}

export { MySharedStateProvider, Context as MySharedStateContext }

Create a hook for your Context, that can be used in any child component

import { useContext } from 'react'
import { MySharedStateContext } from './MySharedStateProvider.js'

export const useMySharedState = () => useContext(MySharedStateContext)

Wrap your components with the provider (I know it wouldn't look like this, it's just an example)

<MySharedStateProvider>
  <Posts/>
  <CameraUpload/>
</MySharedStateProvider>

Now in your Post or CameraUpload component, you use your hook to get the values

import { useMySharedState } from './MySharedStateHook.js'

const Post = () => {
  const { myState, setMyState } = useMySharedState()
}

Matt Sugden
  • 844
  • 6
  • 12