I would like to load data using redux action when the widget is constructed. Let´s say for example:
User opens the app, then the HomeScreen component is rendered, on this page are some categories.
I have achieved to have AppState that supports multiple stores (yet not tested) that is populated with initial data in main() using FlutterStorage.
So in HomeScreen I am able to access data from build() using StoreConnector since in convertor i will get the store, so i can dispatch events or read app state. But this is only inside the build() which is problem, because if dispatch the LoadCategories event in the render method, then it will go into infinite loop.
In reactjs i was able to map dispatch to component (widget) properties so in componentDidMount i was able to fetch data. This seems impossible in Flutter.
Any ideas how to achieve that?
Thank you
Probably not the best answer but I have noticed that StoreConnector has a onInit property which does what I need.
#override
Widget build(BuildContext context) {
return new StoreConnector<AppState, List<Category>>(
onInit: (store) {
store.dispatch(LoadCategoriesAction());
},
builder: (context, categories) {
Your answer is correct, but there is an alternative depending on your use case. According to the doc you can use onInit or onInitialBuild.
onInit
This can be useful for dispatching actions that fetch data for your Widget when it is first displayed.
onInitialBuild
This can be useful for starting certain animations, such as showing Snackbars, after the Widget is built the first time.
Related
I'm new to Next.js and I'm using it to perform server side rendering on the landing page.
The landing page has: 1 generic component that's the same to every user and 1 component that is specific for each user.
Is it possible to perform server side rendering on the generic component, and client side rendering on the specific one?
Thank you.
Yes, you can do client-rendering for any component in your hierarchy. Client rendering usually means that when the component first renders, it fires off some asynchronous request for data (from an API, etc).
In your SSR page, just have your user-specific component not render anything on the initial render (except maybe some loading UI). Then include a useEffect hook that triggers the API call and sets state (local or global state as appropriate) which will trigger your component to re-render with the user-specific data.
During SSR, only the loading state will render. As soon as the component is mounted, the useEffect will trigger and the user-specific data will load and the component will re-render.
Overly simplistic example:
const UserGreeting = () => {
const [name, setName] = setState();
useEffect(() => {
getUserNameAsync().then((data) => {
setName(data.name);
})
}, [setName])
if (!name) {
return <div>...</div>
}
return (
<div>Welcome, {name}</div>
)
}
To make a page both dynamic and static at the same time is possible.
the solution for dynamic: you have to use react useState then useEffect to send the request after unloading fishing on the client side
but first must use next.js api getStaticProps() make the page static user's first visit
I want navigate to another screen while current screen is running. If in Firestore collection new document add then app listen it and navigate to another page. Please help me...
I don't think this is possible with the traditional navigator, however, one way of "emulating" something similar is by using an IndexedStack, which keeps both widgets loaded and you can simply select an index. I've used this successfully when I needed a fancy splash screen and wanted my other widget to load early.
However, it seems to me your problem is more to do with maintaining state. I'd recommend reading Flutter's page on lifting state up. You can use something like Provider above your MaterialApp to keep your data loading even when your widget isn't on screen or simply pass your state back and forth between pages using navigator arguments (I don't recommend that).
You can try something like this
void initState() {
listenFirestore();
super.initState();
}
listenFirestore() async {
Firestore.instance
.collection('availableDates')
.snapshots()
.listen((data) => {
// here you can call navigator method
});
}
Listen to Firebase changes and call a function to navigate for a new screen.
If you are using Flutter Bloc you can do this using BlocListener.
BlocListener official doc.
I am using flutter-redux for state management in my project using StoreConnector.
Lets say I have a list of songs in the main view and a music player widget in the bottom bar. Everytime a new song is clicked on, the music player widget should make an api call for number of people who listened to that song.
So I need to fetch data in this widget not just once but everytime the corresponding store data in _ViewModel for this widget changes.
In react js, we can use ComponentDiDUpdate() lifecycle. I wanted to know if there is something similar in flutter or if there is a best practice for this situation.
You can use StoreConnector event listeners:
StoreConnector<AppState, AppState>(
onDidChange: _onDidChange,
onWillChange: _onWillChange,
);
i have two fields with redux form. I have a refresh button through which i update my state through an action. This refresh button updates three text values. My problem is that i must refresh the field values of my form. How to update the state of my redux form. I'm thinking of using a selector like this:
export const formsState = state => state.get('form');
Then i will create a reducer which is taking the formstate and updates it with
update formsState
.update('order', action.payload.price);
But i dont think this is the best solution. Do have some better ideas?
Make sure you refresh button send an action which will update your store via the reducer.
In order to update your component I would suggest to use a react containers usinng connect.
Use the following function:
store.getState() to get your state.
store.dispatch() to dispatch your action.
Here is my root component in angular-meteor app:
export class RootComponent implements OnInit {
playlists:Mongo.Cursor<any>;
ngOnInit():any {
this.playlists = Playlists.find();
}
}
When I update Playlist collection from another angular(2) component, I see that my view where I am rendering the playlists updates.
That particular view does not have access to any other variable in the other component so it seems obvious that the view is updating because of collection playlist updating.
I was wondering that how is this happening without having that code in ngOnInit update the view without being in Tracker.autorun?
Tracker.autorun() is a way to explicitly create a computation object around some data that you want to be reactive. However, certain things are automatically reactive in Meteor:
Session variables
Template helpers
Publish/subcribe statements
Collection cursors
See here for more info: https://www.discovermeteor.com/blog/reactivity-basics-meteors-magic-demystified/