Iam setting up a global headers for the axios (React Native) so i need to get token from the redux store. But when i try to get it throws error: Invalid hook call
Anyother way around or solutions would be a big help!
import { useSelector } from 'react-redux';
let authToken;
function getToken() {
authToken = useSelector(state => state?.authReducer?.authToken);
return;
} getToken();
You cannot you useSelector in function.
But you can get state by using following syntax.
const state = store.getState()
and then you can get your desired values like
let authToken = state?.authReducer?.authToken;
Hooks are for functional components (.jsx) and not for functions (.js).
Use getState() instead of useSelector.
Related
Is there any way of getting the state value without using useSelector with using it in React Component
import { superAdmin, zoneManager } from './navigations'
import { useSelector } from 'react-redux'
const access = useSelector(state => state.access)
return access
The Error I get is:
Invalid hook call. Hooks can only be called inside of the body of a
function component.
Which I get it but is there any other way of getting the store value without the use of useSelector
Thank You
To make the store accessible anywhere (for whatever reason), you first need to export the store from the file where you are making it:
// fileThatMakesStore.js
export const store = configureStore();
Then, back in your file, you can simply import the store and getState().
import { store } from 'fileThatMakesStore.js';
const someValue = store.getState().something;
const someValue = store.getState().someReducer.something; // If you have multiple reducers
Good to know: The store is just a simple JS object with three functions: subscribe(), dispatch(), getState().
You can use getState of store, like this:
const access = store.getState().access
I'm using react query because it's super powerful but I'm struggling trying to share my data across many components inside a provider. I'm wondering if this is the right approach.
PostsContext.js
import React, {useState} from 'react';
import { useTemplate } from '../hooks';
export const PostsContext = React.createContext({});
export const PostsProvider = ({ children }) => {
const fetchTemplate = useTemplate(templateId);
const context = {
fetchTemplate,
};
return <PostsContext.Provider value={context}>{children}</PostsContext.Provider>;
};
useTemplate.js
import React from 'react';
import { useQuery } from 'react-query'
import { getTemplateApi } from "../api";
export default function useTemplate(templateId) {
return useQuery(["templateId", templateId], () => getTemplateApi(templateId), {
initialData: [],
enabled:false,
});
}
and then my component that uses the context
function Posts () {
const { fetchTemplate } = useContext(PostsContext);
console.log(fetchTemplate.isLoading)
fetchTemplate.refetch() <---- how can I refetch with a different templateId?
return {...}
}
I'm looking for a way to dynamically call my hook with a different templateId but with the hook inside the provider so I can use it all over my app. Is this the right approach? I have deeply nested components that I don't want to prop drill.
You don’t need an extra way to distribute your data, like react context. Just call useQuery with the same key wherever you need to, and react query will do the rest. It is best to abstract that away in a custom hook.
refetch should only be used if you want to refetch with the exact same parameters. For changing parameters, it’s best to. make them part of your query key, because react query will refetch whenever the query key changes.
So in your example, you only need to call useTemplate with a different templateId. templateId itself is local state (which template has been selected by the user or so), and how you make that globally available is up to you.
I am using redux in a phaser and react based game, dispatching actions in React Components, Utils, and Axios API Calls. I know there are useDispatch hook and connect can be used for React Components, however, based on my own experience, I can use dispatch from store directly as well.
import store from 'my-redux/store';
const { dispatch } = store;
dispatch(actionCreator(1));
I use the above way to dispatch actions in Phaser Scene and Utils to change states such as health and score, and dispatch actions in Axios async API calls. It is convenient and light compare to using useDispatch or connect, so why is it not recommended to dispatch from store except for isomorphic app?
Reference for why not use dispatch from store for isomorphic apps:
redux issue!916
redux issue!184
redux issue!362
I even want to bind dispatch to action creators like this:
import store from 'my-redux/store';
const { dispatch } = store;
export const handleSetSomeThing = (state) => {
const action = {
type: ActionTypes.SOME_TYPE,
payload: state,
};
dispatch(action);
};
Then I can call the above function like this without importing store or using connect, redux hook:
handleSetSomeThing({ health: 5 })
Any idea?
Suppose I have a react pure function named SignIn() in One.js :
import React from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import {GoogleSignin, statusCodes} from '#react-native-community/google-signin';
import {getToken, saveToken} from '../actions/token';
const SignIn = async ({token, getToken, saveToken}) => {
const savedToken = await getToken();
console.log(token.loading, savedToken);
SignIn.propTypes = {
token: PropTypes.string.isRequired,
getToken: PropTypes.func.isRequired,
saveToken: PropTypes.func.isRequired,
};
};
const mapStateToProps = state => {
console.log('state : ', state);
return {
token: state.token,
};
};
export default connect(mapStateToProps, {saveToken, getToken})(SignIn);
I want to use this SignIn() function in another Two.js react file so that getToken() which is a redux function and other functions will be called inside file One.js and then i can use those functions inside file Two.js but the problem is because of redux connect, i am not able to export and use them. How can i import and use this kind of function inside Two.js file ?
connect function can only be implemented with react components that renders actual jsx, and for it to work you need to return jsx elements or null and call it like this <SignIn />.. in my opinion if you want to implement some logic with the use of redux, you can make a custom hook, implement useSelector or useDispatch inside it, and either return the data you want or just do your effect inside it then return nothing.
hope this helps.
here's an example from react-redux docs https://react-redux.js.org/api/hooks#usedispatch
What Worked for me was declaring the functions that i want to export inside the redux actions, so i created a new action for any function that i want to use. Make sure to make use of loading state of initial state otherwise functions can be called infinite times because of re-rendering.
I want to use nextjs in my new project with redux and thunk also. I wondering how to implement all packages correctly.
In my previous projects pages has HOC components like:
import {connect} from 'react-redux';
import Page from './about';
import {fetchUsers} from '../../actions/user';
const mapStateToProps = (state) => {
const {users} = state;
return users;
};
const mapDispatchToProps = (dispatch) => {
return {
fetchUsers: () => dispatch(fetchUsers())
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Page);
And method to fetch users I implemented in componentDidMount
How to implement the same logic for nexjs?
What have I do?
Implemented store (base on next-redux-wrapper in _app.js)
Created HOC component (like below) with mapStateToProps and
mapDispatchToProps
Currently I thinking about use somehow this.props.fetchUsers method into getInitialProps - documentation say that this method should be used to fetch data before render site.
Please help me with correctly redux implementation for nextjs
You can follow this example
The correct way is to pass the store to the getInitialProps context and to the App component so you can pass it to the Provider.
The getInitialProps can't access to instance of the component, this is not accessible, so you can't call this.props.fetchUsers, but, because you are passing store to its context, you can do store.dispatch(fetchUsers()) and remove dispatch from mapDispatchToProps.
Generally I dispatch actions in getInitialProps and then map state to props within connect.