Redux: share a regex between back and front-end - reactjs

I need to share some static data between my rails app and the redux-based front-end. The example in this case is a regular expression used by a helper method in the js and also in a controller in the rails app.
I feel it's annoying having to add something like this into the redux store since the store is not easily connected to from independent helper files in the js. Instead you would need to grab it in mapStateToProps, pass it as a prop into a presentational component, that would then send it through in an action, so that the code that handles actions (either in mapDispatchToProps or reducer) could send it through as a param when using the helper method.
Seems like a lot of unnecessary passing around for something that never changes. Are there any standards for static data provided by the server to be used in the front-end? Maybe adding something to the window object?

If its something that truly never changes, here are some ideas:
Have a configuration endpoint where you can get the regex and drop into redux state
Static config file that can be shared by JS/Ruby code
Hardcode the regex directly into the reducer's initialState
Create a javascript file and hardcode the regex directly into that file. Maybe put it in a file indicating its shared with the server.
Using the window object will make all serious react devs cringe a little. Eventually, that value could change, and it is going to cause bugs all over your app. If you are confident to make that gamble, then do it. Using the window object may make testing more difficult as well.

Related

Where should I put API call which is requesting user data

Where should I put get user data API call which is requesting user data such as username, email from JWT token stored in localstorage.
Should I call it from _app.js pass it to the components or should I create redux store and save these data.
Using redux only for that purpose is an overkill. You should create context and wrap components, which are using this data. Also there is hook called useReducer, combined with context API allows you to achieve redux behavior.
Passing user data down to components directly is not a bad idea if you have only 2 level depth structure which is often not the case.
For this purposes is a nice option to use tools like Redux or React Context API. That way you can access the global state from whichever component you like in the same way, which leads to more readable and maintainable code. For more information about Redux vs Context API, consider looking more in-depth to understand the differences and decide which one is more suitable for your case.
For me personally, the Context API can do the work in more of the cases which is fine. Also, it is already part of React, and it's not a dependency like Redux is.

React admin 3.x useDataProvider loading indicator

In version 2.x when you used the hoc withDataProvider and you used the dataProvider injected into the props, you could pass some extra options like onSuccess, onFailure and additionally using that dataProvider made sure all the proper redux actions were called. So you could see the loading indicator and whatnot.
Now with the new hook, you can no longer pass on those options. So you are forced to use also useNotify, useRefresh, etc.
I noticed that also no redux actions are being called.... so no loading indicator.
So basically my question is how to use the dataProvider and have it show the loading indicator, but it could be well be paraphrased as have it run all the redux actions that are normally ran when you use the default components like List or View
When migrating from 2.x to 3.x, you have to migrate your custom data provider.
If you had the old kind as specified in 2.x where you used constants:
switch() {
case MY_CUSTOM_ACTION:
}
Which was used like this:
dataProvider(MY_CUSTOM_ACTION...
This old way keeps working, however the redux actions are not dispatched.
Once you migrate into the new way of writing the data provider everything works as expected. https://marmelab.com/react-admin/DataProviders.html#data-providers

Is there a way to access Context in a Redux Thunk?

This is more of an understanding question and I also want to know the community thoughts, rather than a code question.
We have a React App using redux for managing the global store and redux-thunk for dispatching actions. Now we want to localize the App and add a language switch. For that purpose I created a HOC which uses React.Context to store the dictionary for current language in it. And I wrapped all Components in this HOC - everything works just fine.
But we also need to access to the dictionary in the thunks to e.g. provide success/error messages after API calls in the selected language. It seems to be impossible without passing dictionary into thunks.
I've read a lot about Context API and when to use it and that it has different purpose than Redux. That's why I put the translations in the Context and not in the store, mainly for this reason. But now I'm getting the feeling that I missed something and should actually put the translations in the store instead to not be forced to pass the dictionary to the thunk every time I need it there. Is it so?
Or is there a way to implement something like getContext similar to getState from redux-thunk?

What would be the correct way to communicate with redux-react application from another js module

I have a complex form built with react-redux, and I need to know whether this form is valid from another javascript on the same page. Some jquery module.
The easiest way would be add valid/not_valid dynamic class to the react form, and to do something like
$('#myform').hasClass('valid')
But let's say that validation is not the only thing I need from this react app and I want to build a kind of interface for that with some getters. e.g.:
isValid(), getTitle, doSomethingElse methods.
what would be the right way to do that?
Ideally you would store any information you need outside the React application within the store, then simply access the store within whatever jQuery you are writing. This would also work going the other direction, update the store with any particular data that the React application might need to be aware of.
One possible approach:
You can try saving the reference to the store that you instantiate in a global variable.
E.g. Let's say in your top-level React compnonent App.js you do
import MyMainStore from '..../MyMainStore';
.
.
.
<Provider store={MyMainStore}>...</Provider>
//Then finally also do
_MyApp.ReduxStore = MyMainStore;
That way in the non-react/redux part of your app you can access the state via -
_MyApp.ReduxStore.getState().myFormReducer.someExpectedState
Look forward to hearing if that works for you.

How to pass application settings to store

In terms of clean react application design, I'm sure sure how to pass around application settings to modules which are not part of the component tree.
E.g. I connect to a REST API and therefore need to propagate the hostname to the components, but also to the store - I'm using Reflux.
Passing the setting down to components can be easily achieved via contexts, but since the store is not part of it, what's the cleanest way?
So far, I consider these approaches:
Passing the setting from the component to the action, to that I receive it on every store listener.
Use some DI container which is initialized in my index.js and can be used in my store
Both don't seem to be ideal for me. Any hints appreciated!
In most cases you should not keep application settings in store.
You should think about your application like some kind of function that receives state as parameter and returns view. Changes in application state (usually) lead to changes in resulting view. Flux stores are the way you're keeping this state. API hostname is not that stuff which you expect to affect your application. It is just an information payload that your app need to know to work correctly (say configuration, not the settings). So, you should keep it as information payload. Module, class, global variable, some kind of DI, you can consider anything that you find useful to work with.
I usually create separate module exporting object with all configuration. Something like:
const config = {
api: {
hostname: 'localhost',
port: 3000
}
// ...
};
export default config;
And then just importing it. Something like:
import config from "../config";
const api = new API(config.api); // just for example
But if you really need to work with some kind of settings that can affect UI (an example is delay to show popup; it example can be even better if we consider changing this delay depends on user's actions) you should create Settings store and work with it like with a regular flux store (subscribing to change, changing with actions so on).

Resources