React-Native - lifting state up in functional components - react-native

I am trying to share the state from child components to parent component , not using state management , all the components are functional components , how can I do that without using state management like redux or context API ? I have checked the listing state up all the the examples and documentation are in class components , please help me with the same ,thanks

Sharing state between components is really all about prop drilling, that is to say, passing props a parent component receives to its child component. Because props are passed on with JSX there is minimal difference between prop drilling in a functional component and a class component.
The biggest difference would be at the top level component where the state and its modifier function are passed to the first child component. This difference is very trivial, e.g
// accessing state variable and state modifier in class component
<CustomComponent
user={this.state.user}
setUser={
newUser=>this.setState(prev=>({...prev,user:newUser})
}
/>
// accessing state variable and state modifier in functional component
<CustomComponent
user={user}
setUser={setUser}
/>
Even so, this react doc gives a basic example of efficient prop drilling that uses functional components

Related

Can i make it happen has() in vue.js?

i'm using vue.js and vuetify.
elements made by parent element exist in my code.
i want to change parent element's class dynamically depending on it's child class, like jQuery has() method.
is vue.js has any way to do this?
jQuery has()
You can access a state if a child property of a child on different ways. (I assume the child class is set based on a certain state).
You could use vuex that keep a state over several components. You could emit a state back to you parent component. Or you could use the ref to access the child components properties.
<component ref="childcomponent"></markdown>
process: function(){
// items is defined object inside data() of the child component
var hasClass= this.$refs.childcomponent.item
}

Vue JS Components structure

I am learning Vue and my doubt is about the structure of my Vue app.
I learnt that the components can include both logic and template. Then I separated my components and everyone is getting the config from the main app (config is an object with the coordinates config.ll, config.lng).
I do the ajax call to my search-and-discovery API service and I display the results inside each components (current location, venues-near-you etc).
My question is: is it correct to encapsulate the calls into each components? Or is it better to get the needed data inside the general app and then share the results with the components using pros?
I am asking that because the hard part is starting now when I want to communicate the click of a category to the venuesNearYou component, I tried to use the emit without success.
//MAIN
<sidebar :config="config"></sidebar>
<content :config="config"></content>
//IN SIDEBAR
<currentLocation :config="config"></currentLocation>
<categories :config="config"></categories>
//IN CONTENT
<venueDetails :config="config"></venueDetails>
<venuesNearYou :config="config"></venuesNearYou>
I think you could use event Bus like approach
we have three type of communication in vue app (without vuex)
Parent to child communication which is full field by props
child to parent communication handle by custom event from child which is listen by parent
communication between non parent child component in which we use event bus approach
Parent to child example
Child to parent example
In child this.$emit('sendDataToParent',{someData:"some data"}})
in parent
<child-component :somedata="dataToChild" #sendDataToParent="'gotsomedata from parent'">
Event Bus
in main vue instance
const eventBus = new Vue()
in some component from where to send data
import eventBus
eventBus.$emit('someEvent','some data')
in some component from where to receive data
created() {
// register listener
eventBus.$on('someEvent',()=>{
})
}
For more reference
https://v2.vuejs.org/v2/guide/components.html#Passing-Data-to-Child-Components-with-Props
https://v2.vuejs.org/v2/guide/components.html#Emitting-a-Value-With-an-Event
https://medium.com/easyread/vue-as-event-bus-life-is-happier-7a04fe5231e1
It's hard to help you around emitting an event since you didn't provide much of a code. But check Vuex. It serves as a centralized store for all the components in Vue application.

How to pass props on React-Navigation so the navigated component can re-render when those props are changed

im trying to navigate from component A to B passing props this way (as options):
this.props.navigation.navigate("B",{
retrievePlayingNow:this.props.retrievePlayingNow, // props come from component C
skipSong: this.skipsong, // this is a function
});
}
so when i call a function 'skipSong' it changes the props on component C (which is a father component of A)props on A changes but on component B props remain the same and it doesn't re-render to show the new info. Is there any other way i can do this using React-Navigation?
This is where a state management libraries comes into action.
Well, I use redux. Here you can store the data in the global store which can be accessible by any of the components.
So put the variable retrievePlayingNow into the redux store from C component, and access it by B component. So when C (or anyone) changes the value of that variable, all those components using accessing that variable (including B) will re-render.
Another advantage of using any state management library is that you don't need to make a hierarchy of components to pass props as you have done C -> A -> B. All you can do is dispatch the variable into the store from C and directly access it by B
You can use DeviceEventEmitter to add listener events to re-render without using redux.

How to check when a React Native component has finished RE-rendering?

I am currently re-rendering Child components within a Parent component based on a state change and I need to know when the child component has completely mounted and re-rendered on screen. Here's a quasi-example:
<Parent>
{ this.state.showChild1 ? <Child1/> : <Child2/> }
</Parent>
The general procedure for responding after state change would be using componentDidUpdate(prevProps, prevState) however, this lifecycle event only fires after state has updated without considering the effects of what the state change would update within the <Parent> component.
The problem I'm encountering then is that although state has completely updated, the new Child component is not yet available because it hasn't actually finished re-rendering yet. Is there a way to check when the Child components have re-rendered?
You could pass a callback into the component (sth like isMounted()) and call it in the child in the componentDidMount and componentDidUpdate lifecycle hook.
If you need this with arbitrary components you could iterate over them with React.Children.map(see docs) and add the lifecycle hooks on the fly (this is a bit error prone and you would need to have class components)

Why react-native routers use state instead of props?

There is an official react-native example regarding routing which uses props instead of state.
However all other router component libraries use state instead of props. Especially, the libraries that have prepared for Flux and Redux usages.
What is the main idea of state usage in router components?
The reason why they use navigator=this.props.navigator in this example is that this is a child component, where a parent component is passing down its navigator to the child through props. You generally do not pass down state directly into a child component, you pass down a prop that could be used in "getInitialState".
https://facebook.github.io/react/tips/communicate-between-components.html
Here we see that this is simply the syntax used to pass a prop from parent to child. We want to pass the navigator between different components so that the app is consistent, they are all using the same navigator to navigate between different pages.
Just a warning though, when passing props as state to a child component, note it should be clear that it's only for initialization.