Accessing state outside a component with react-redux - redux

I have a large react-redux based application in development. I'd like to add some utility functions to a js script that does not contain a react component to "connect" to. How do I access the state in react-redux without a component? Neither mapStateToProps nor mapDispatchToProps are available - do I need to export the state object from the top-level index.js file? Seems dangerous.
Suggestions welcome!
JB

Workaround way:
Import your store inside the scope of your utility functions.
Importing the store (which you would have created while setting up your app) will provide dispatch and getState methods using which you can get access to your state vars.
src/store.js
import ReduxThunk from 'redux-thunk';
import { createStore, applyMiddleware } from 'redux';
import logger from 'redux-logger';
import reducers from './reducers';
var middleware = [ReduxThunk];
if (process.env.NODE_ENV !== 'production') {
middleware = [...middleware, logger];
}
const createStoreWithMiddleware = applyMiddleware(...middleware)(createStore);
export default createStoreWithMiddleware(reducers);
helper.js
import store from "./store"
const { var1, var2 } = store.getState();

The phrasing of your question is just a bit odd. If you're asking about accessing the store in utility functions that aren't related to any components, then you aren't using React-Redux to do so :)
In this case, you would either import the store directly into those utility function modules, or call the functions from some scope that does have access to store capabilities (such as a thunk action creator that was dispatched from a connected component).
There's a related Redux FAQ entry on why you should generally prefer to not import the store directly.

No really graceful way to do it. Long argument list it is.

Related

How to create a global context in Fresh Deno?

I want to create a global instance of GunDB so that it only initializes once on the client side and I could then use it on any island.
I tried in index.tsx to simply add const gun = Gun() and send props to the island, the only problem is that then the island component does not see the Gun instance, which is normal because the Gun instance is initialized on the server side and not the client side.
In theory, it only needs a global context on the client side. Something like createContext() in react.
Fresh v1.1 adds Preact Signals support.
Preact Signals:
Signals are a way of expressing state that ensure apps stay fast regardless of how complex they get. Signals are based on reactive principles and provide excellent developer ergonomics, with a unique implementation optimized for Virtual DOM.
…
// Imagine this is some global state that the whole app needs access to:
const count = signal(0);
function Counter() {
return (
<button onClick={() => count.value++}>
Value: {count.value}
</button>
);
}
You can create a module that exports a signal for your global Gun instance:
import { signal } from "#preact/signals";
export default signal(Gun());
Then you can import this in any interactive island module to use it both server-side and client-side:
import gun from "./path/to/gun.ts";

Using vuex with Vue 3

Last year I spent some time learning Vue 2. I really enjoyed the framework but did not move forward with a project. I now have time for a project but I'd like to use Vue 3 with the composition API. I'll be using Firebase as the backend. I've seen conflicting techniques on whether or not to use Vuex.
For example, I'd like to store a "currentUser" object in global state that can be accessed from any component in the app. Normally, it would be done using Vuex. I'd have a getter to return the object, an async action to get the data from firebase and a mutation to set the state.
However, I've seen several Vue 3 code examples that do not use Vuex at all, instead they do something like this to get/set a currentUser in an app wherever it is needed for example in a navbar component.
composables/getUser.js
import { ref } from 'vue'
import firebase from 'firebase/app'
// refs
const user = ref(firebase.auth().currentUser)
// auth changes
firebase.auth().onAuthStateChanged(_user => {
console.log('User state change. Current user is:', _user)
user.value = _user
});
const getUser = () => {
return { user }
}
export default getUser
With this little bit of code above, I'm able to import getUser.js and access the currently logged in user using code like this. Also, the user object is now reactive:
<script>
import getUser from '../composables/getUser'
export default {
setup() {
const { user } = getUser()
return { user }
}
}
</script>
It seems I can use these little functions to get data from db directly without the need to use the Vuex pattern, which I find to be a bit more complicated.
So, my question is - if I'm starting a new Vue 3 project, is it ok to create "composable" functions to get/set data and import them into my components instead of using Vuex? Are there any downsides to this method? Or should I just stick with Vuex?
Short answer - You don't need it.
Long answer - It depends.
It depends mostly on your app and how often do you use "currentUser" data inside your components. If it's in 2 or more components, how often do you want to perform actually fetching from backend?
Once on app-init/login or every time each component mounts?
(probably once)
Does it need to be reactive? If yes - then you'll probably use centralized data pattern, your own or a library. Taken that into consideration it's probably more simple to just use Vuex.

Exclude redux-form reducer from main store

import { combineReducers } from 'redux'
import { reducer as form } from 'redux-form'
combineReducers({
router: connectRouter(history),
form,
....
// huge amount of other reducers
})
Above you can see combined reducers in one store. As bigger it becomes as slower it becomes because on each action it should make many more checks as it was at the beginning. As you also can see I use redux-form for handling state in my form. And it starts to be slower and slower when I type in redux-form fields. I want to find out is there any way to create some individual store for redux-form, and prevent this from slowing down. Or is there exist some other solutions to this problem?
Using redux you can have multiple stores.
redux-form is using connect API from react-redux to get info from store.
With React Redux, the wrapper classes generated by the connect() function do actually look for props.store if it exists, but it's best if you wrap your root component in and let React Redux worry about passing the store down. This way components don't need to worry about importing a store module, and isolating a Redux app or enabling server rendering is much easier to do later.
https://redux.js.org/faq/store-setup#can-or-should-i-create-multiple-stores-can-i-import-my-store-directly-and-use-it-in-components-myself
I'm a redux-form collaborator.

Using firestore.Timestamp.now() in Angular unit test

I am developing an Angular application, with angularfire2 5.0.0-rc.10. I really hope I don't mess up any terms in the following, but here we go.
I have converted Date's, to the new firestore Timestamp type. This gives me a problem when writing tests. I can only do the following:
import { firestore } from 'firebase/app';
it ('should create', () => {
firestore.Timestamp.now();
});
If I initialize firebase in my TestBed module with:
AngularFireModule.initializeApp(environment.firebase),
Otherwise I get the error:
TypeError: Cannot read property 'Timestamp' of undefined
So my questions:
Is this intended behaviour?
Are you not supposed to be able to create a firstore Timestamp data type, outside of an firebase angular project?
Why is firestore undefined when imported without the initializeApp?
Thanks so much for your help.
I resolved it below
angular version is 11.1.2
import firebase from 'firebase/app';
import 'firebase/firestore';
import Timestamp = firebase.firestore.Timestamp;

the different usage of applyMiddle in Redux

I can see there are two ways to call applyMiddleware.
The first one is
import thunk from 'redux-thunk'
const middleware = [ thunk ]
const store = createStore(
reducer,
applyMiddleware(...middleware)
)
the other one is
import thunk from 'redux-thunk'
let store = createStore(reducer, applyMiddleware(thunk))
so when should I use the first one and when should I use the second one?
thanks
They are pretty much completely identical. The first example is a little more robust, in that it would be easier to add a second middleware if you wanted (by having two elements in the const middleware array). But the second one is shorter and does exactly the same thing, and works great if you only need to use one middleware.

Resources