Cannot update props passed via react navigation - react-native

I have a container where the API calls happen. I need to pass the response I get to another component which is not the child of the above container. I can't pass in props like how you usually do since it is not a child component of the above container. What I do is, I pass the response to the above container's child component and from there I use :
this.props.navigation.navigate('Whatever',{
reason: this.state.reason
});
To pass in the reason as prop to the "Whatever" component. Now, the problem is this "reason" prop does not get updated when it changes in the container from where it is being passed.
Now, I am aware that since we are not passing props like how they are usually passed that's why we won't be able to get the updated props in whatever component. I am aware that I might have to change the structure of my app as well, but I cannot afford that right now.
Is there any way via which I can update the reason prop in the whatever component?
Thanks in advance.

You can use params in react navigation
--updating params https://reactnavigation.org/docs/params/#updating-params
--passing params https://reactnavigation.org/docs/params/#passing-params-to-a-previous-screen
--passing params to nested component https://reactnavigation.org/docs/params/#passing-params-to-nested-navigators

Related

Using Intertiajs with Element UI

I am using Inertiajs
with Laravel and also trying to use Element UI components but as i use Menu component i am having following error in console, I just used example as given in Element Ui Components as i was testing.
I see 2 different errors in there, both of them are with props.
I assume your component is taking the route as a prop, and you are also using the route as a method, which you might have put inside methods: {} which is not allowed. Make sure you rename your method route to something else.
Note: As a matter of fact you can't have any data coinciding with each other. your props, data, computed props and methods all should have unique names.
You are trying to use v-model on the props directly which won't work in Vue. if the prop is a primitive (Number, String, Boolean etc). but you can pass Object or an Array which can hold a reference to the data. This is because reactivity in Vue can't keep track of props when passed as primitives.
More on prop mutations here: https://v2.vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow

Pass hidden data with vue-router

I would like to pass data when navigating from one route to another, but the data shouldn't be shown to the user in the URL, as it is with route parameters.
Instead, I want the data to stay "hidden" from the user, since, in my case, I want to pass an authentication key (which is pretty long and shouldn't necessarily be shown to the user).
Is this achievable using router.push()?
What I think I would do to solve this, is to define props, just below where you define your path, you can add props to it. See: Passing props to Route Components
Essentially you define what do you want to pass, an object, a value, whatever you need. And within your router-view component, you bind the prop that you want to pass.
For example:
: is shorthand for v-bind
<router-view :props-name-defined-in-router="value"></router-view>
Remember to use the proper casing in Vue.js See: Component name casing in templates
Additionally, I think this other question seems to fit your needs.
Passing props to Vue.js components instantiated by Vue-router

Props not propagating to children

I'm working on adding swipe to remove functionality to an app we are developing. For reasons we are not using an external library to handle this, so I am writing it myself.
In my project I have a container where I keep state. I use setState to update the state, and am passing state down to this child component as a prop. In the component below, componentWillReceiveProps is called with the correct value updates when they happen, but the child component of this is not receiving updates to its props. If this doesn't make enough sense or you need to see more code let me know. I've only included the parts of code that I feel are relevant since this is a private project.
constructor(props) {
super(props);
this.renderWishlistRow = this.renderWishlistRow.bind(this);
}
renderWishlistRow(product) {
return (
<WishlistRow
item={product}
onItemPress={this.props.onItemPress}
onRemoveAction={this.props.onRemoveAction}
shouldCloseRemoveButton={this.props.shouldCloseRemoveButton}
onScrollAction={this.props.onScrollAction}
itemPressed={this.props.itemPressed}
onEndScroll={this.props.onEndScroll}
/>
);
}
Then, inside the render function:
return (
<KeyboardAwareListView
dataSource={this.props.dataSource}
renderRow={this.renderWishlistRow}
renderSeparator={renderCardDividerAsSeparator}
onScrollBeginDrag={this.props.onScrollAction}
scrollEventThrottle={16}
onScrollEndDrag={this.props.onEndScroll}
/>
);
Thanks in advance for any help.
EDIT:
I am setting state in the parent component with this code:
this.setState({
shouldCloseRemoveButton: true,
});
I didn't originally include it because componentWillReceiveProps is being called with the correct state changes from the parent component.
EDIT 2:
My App Hierarchy for this part of the app is as follows:
WishlistContainer: contains the setState calls and passes as a prop: shouldCloseRemoveButton={this.state.shouldCloseRemoveButton}
Wishlist: passes props to its child WishlistRow: shouldCloseRemoveButton={this.props.shouldCloseRemoveButton}
WishlistRow: Continues to pass the props down as above, but componentWillReceiveProps is not called here, props are not updating at this level.
I'm not going to mark this as answered, because I want a real answer and what I did to work around this is not good enough for me.
That being said, my workaround was to move the piece of state I was trying to propagate into react-redux. Setting the redux state to contain what I needed using mapDispatchToProps, and then connecting the components that actually needed the state down the line using mapStateToProps, allows the components to receive the notifications they need to do their thing.
Again, I am not choosing this as the answer - even though it is what I did to solve the problem - because something else fishy is going on somewhere and I would like to see if anyone knows why things didn't work as they were.
EDIT
I've run into this issue other times since this originally happened. There is a prop that exists on the Flatlist - This is not the original component I used in the question, but the original component is deprecated now and the Flatlist has the, about to be mentioned, prop for this scenario - called extraData. This particular prop is also watched to help the Flatlist determine if it should rerender itself.
Since the ListView has become deprecated, I feel that using a Flatlist and making sure you pass in an extraData prop - assuming you have a different prop that will change with your list data changes - is an acceptable answer to this problem.

Mutations using Relay Environment

I'm using Relay with React Native and have a problem during login & logout.
After login or logout, Relay keeps the store from the previous user. To solve this I use Relay.Renderer and Relay.Environment. As in, in each Renderer I put singleton object of Environment.
The problem is that I previously did a mutation on object of Relay.Store, as in
Relay.Store.commitUpdate(new CreateProfile(), callback).
Now it doesn't work. I guess this is because Relay.Store doesn't know anything about server endpoints. But Relay.Environment does.
And now I'm using something like this this.props.relay.commitUpdate(new CreateProfile(), callback). It works pretty well when the parent component is wrapped as Relay.Container, so it has relay object in props.
But what should I do in components which are not Relay.Containers and don't have Relay object in props?
Relay.Store is a globally accessible singleton instance of Relay.Environment and Relay.Store.commitUpdate() updates data in that global environment. But since you're using your own instance of Relay.Environment, to update it you need to use this.props.relay.commitUpdate(), as you noted. This updates the environment the container was rendered with.
If need to make mutations from child components of containers, that are not wrapped in a Relay.Container, there are two ways to do that. You could simply pass the relay prop to them, so in the render function of your container you would have:
<Child relay={this.props.relay} />
However, since those plain components are not in a Relay container, they don't currently need to know anything about Relay. If you want to keep them that way, you could write the method that does the update in your container component like this:
onCreateProfile = () => {
this.props.relay.commitUpdate(new CreateProfile());
};
and only pass a callback to your child component in render:
<Child onCreateProfile={this.onCreateProfile} />
If you need to make a mutation from a component that does not have a Relay.Container above it in the component hierarchy at all, you could create the Relay.Environment in a shared root component higher up and pass it down using props (or pass a callback using the strategy shown above).

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.