marudy / react-native-responsive-screen

Make React Native views responsive for all devices with the use of 2 simple methods
MIT License
1.56k stars 142 forks source link

React-native with hooks #39

Closed ismaelsousa closed 4 years ago

ismaelsousa commented 4 years ago

How do I use orientation with hooks?

randowize commented 4 years ago

How do I use orientation with hooks?

You could use the following approach:

import React, {useState, useEffect, useMemo} from 'react';
import { 
listenOrientationChange as lor, 
removeOrientationListener as rol
 }
 from 'react-native-responsive-screen';

const Component = () => {
    const [state, setState] = useState({});
   const that = useMemo( () => ({setState}), []);
    useEffect(() => {
        lor(that);
        return rol;
     }, []);
}
// your code continues here
ismaelsousa commented 4 years ago

Is that "that" in lor (that) part of the component? and what is this code doing? const that = useMemo( () => ({setState}), []); he is putting the screen value in the variable state?

randowize commented 4 years ago

Is that "that" in lor (that) part of the component? and what is this code doing? const that = useMemo( () => ({setState}), []); he is putting the screen value in the variable state?

@ismaelsousa that "that" is just to mimic the react class component API. If you take a look at the implementation of 'listenOrientationChange' you'll notice that it expects an instance of a react class component, not a stateless function component. Take a look a this line where a call to setState is made. So in order to satisfy the listenOrientationChange api, we create a fake instance (that) of a react class component. The useMemo is just an optimization trick, you can remove it. Last but not the least, the current orientation will be store in the state variable.

Yhozen commented 4 years ago

What I did is: I created a new hook called useOrientarionChange like this

import { useState, useEffect, useMemo } from 'react'
import {
  listenOrientationChange,
  removeOrientationListener
} from 'react-native-responsive-screen'

export default () => {
  const setState = useState({})[1]
  const fakeThis = useMemo(() => ({ setState }), [setState])
  useEffect(() => {
    listenOrientationChange(fakeThis)
    return removeOrientationListener
  }, [fakeThis])
}

so that you can just do

import React from 'react'
...
import useOrientationChange from 'PATH_TO_HOOKl/useOrientationChange'

export default props => {
  useOrientationChange()
  const trailers = useNavigationParam('trailers')
  ...
}

in any component that you want to listen to orientation changes, maybe it would be a great idea to add that hook to the package

vankhoa01 commented 3 years ago

Hi @Yhozen , I'm newbie with RN I tried with your code, but I'm facing this error:

Screen Shot 2021-07-06 at 13 47 15

Could you please give me some hint to fix this ? Currently I'm using latest version of react-native-responsive-screen and React Native version 0.64.2

Thank you so much

ismaelsousa commented 3 years ago

Hi @Yhozen , I'm newbie with RN I tried with your code, but I'm facing this error:

Screen Shot 2021-07-06 at 13 47 15

Could you please give me some hint to fix this ? Currently I'm using latest version of react-native-responsive-screen and React Native version 0.64.2

Thank you so much

give more context,pls, and put the code here, but seems you trying to pass a variable to a method that no expect this.

Yhozen commented 3 years ago

Hi @Yhozen , I'm newbie with RN I tried with your code, but I'm facing this error:

Screen Shot 2021-07-06 at 13 47 15

Could you please give me some hint to fix this ? Currently I'm using latest version of react-native-responsive-screen and React Native version 0.64.2

Thank you so much

That is a type error, your code your work anyway but if you want to get ride of that error, you can create a custom hook like


import { useState, useEffect } from 'react'
import { Dimensions } from 'react-native';

const useOrientationChange = () => {
  const [_,setState] = useState()

 useEffect(() => {
    Dimensions.addEventListener('change', newDimensions => {
    // Retrieve and save new dimensions
    screenWidth = newDimensions.window.width;
    screenHeight = newDimensions.window.height;

      // Trigger screen's rerender with a state update of the orientation variable
     setState({
        orientation: screenWidth < screenHeight ? 'portrait' : 'landscape'
      });
    });
   return () => Dimensions.removeEventListener('change', () => {});
 }, [setState])
}
vankhoa01 commented 3 years ago

@Yhozen : Thank for your supporting Let me try with your solution Thank you so much