Redux hooks in regular function (rules-of-hooks) - reactjs

I'm having a trouble with a regular function. In my component, I'm loading lot of products with a function that is reusable everywhere. So I have a file named products.js where some functions are defined.
In a function called 'getPrice', I need to get a param called 'beautifullPrice' stored in the redux store, on a reducer.
If I do it respecting hooks rules, I have to implement useSelector in my components and pass 'beautifullPrice' as a param in every functions. But my 'getPrice' is a sub sub sub call. So I need to declare 'beautifullPrice' in tons of functions, and this param cant change till the application is not reloaded.
So, in my opinion, the easiest way to do this is to use useSelector directly in my function 'getPrice', all my functions wont have one more params, it will be cleaner. But according to react-rules, I should not do this.
First question : Why this rule ? I tried and it seems to work well.
Second question : Is there an other proper way to do this ?
Am I the only one facing this type of problem ? =D
Thx for reading, and for help !

Related

How to prevent refresh of list over API after drag & drop with beautiful DND?

I simulated my Context + DND problem in https://codesandbox.io/s/adoring-booth-33vqo . I have other components which will be added to this example and I will use a Context hook to share values across the page.
After the initial render, everything looks fine. The idea of the list is to change the order within itself and when ones changes the order with drag-drop, it throws an "Invalid Hook" error.
So the (first) real question is, what is triggering this error which is linked to the line
const { lang1Library, updateLang1Library } = useContext(LangContext)
;
Thanks in advance for your help.
Geo
It's not a good approach to provide a link for the whole project even if it is small. But I had a quick look and there's at least one thing you're doing wrong:
// DragEndFct.js
export default function DragEndFct(result, libName) {
const { lang1Library, updateLang1Library } = useContext(LangContext);
This is not React component, but it uses a hook - and it is wrong. Hooks have a special meaning in React and should be used properly (Rules of Hooks).
You can't use hooks inside regular functions and expect them to work. That is why you are getting that error.
So, there are many ways you can try to fix this. For instance, DragEndFct is a regular function, you can declare more arguments and pass stuff you get from context:
// you are using it in components right ?
function DragEndFct(result, libName, param3, param4) {}
// so you probably have access to the context there
// and can pass data from the context when you call it.
// something like this
onDragEnd={function (result) {
console.log();
DragEndFct(result, StaticVars.LANG1_LIBRARY_NAME, lang1Library, updateLang1Library);
}}
You could even make DragEndFct to be a React component - it can just return null (which means no UI will be rendered) but in that case you will have hooks and all other stuff there. It really depends on what you need and how you will use it.

Mobx. Getting value from another store

I have Mobx FirstStore and import SecondStore. SecondStore has a (value) and I want to use it (value) in my FirstStore.
As shown in the screenshots, this is how it works, but I have a question, is it safe to use it? If (value) changes in my SecondStore, will FirstStore see it?
Perhaps it is better to add a parameter and pass (value) through the React component when calling the function?
async someFetchRequest(valueFromSecondStore) {
await api.retData(valueFromSecondStore)
}
Thanks in advance!
======================================================================================
It is totally fine to use it like that in most cases.
There are cases when you might consider different approaches like Dependency Injection, or just pass values as parameters like you said. But until you encounter those advanced scenarios (make testing more approachable, for example, or server side rendering) you can safely use it like that. You can even make computed getter in the FirstStore, or reaction, with some value from the SecondStore and it will work as expected.
You can also encounter circular dependency loop in some rare cases if you import class A to class B and class B to class A, but if you only import them one way you are fine.

React hook - Can I use common variable out of function(hook) or Is it anti-pattern?

I recently use react hook well. however sometime I wonder my coding style is okay.
let mDown = false;
let timerId = null;
function App() {
useEffect(() => {
mDown = true
....
}, [])
}
Like bottom code, I declare variable out of function. and I want to use common variable and access, change this value without using state.
Is it anti-pattern?
Thanks to read. :)
yes, of course. you can use the common variable in not only the hook function, but also any other methods of the App.
however the best practice is to make the global variables in other js files like constant.js, and import them in the above of the file.
import { mDown, timerId } from '../constant'
So let's think in terms of components. I mean, let's ignore for a while there barely will be more than one <App /> but think about component-centric approach in general.
Do you mean some data independent for each component's instance? Then you use useState(if changing this data should re-render component) or useRef(if updating this should never trigger re-rendering).
Or should that data be shared among all the components? Then, again it depends. Sometimes global variable is fine(real global variable, as a property on window object), sometimes better to put it into Context API or any state management layer(Mobx, Redux) instead.
Why don't have module-level variable as you aer going to? I see multiple reasons(again, maybe not big deal for exact case with <App />):
Module-level variable sticks to module instance. If we you ever end with multiple version of the same component in the same application, they will have own instances of such a variable. Think of <Dropdown /> component and some variable made to collapse all other instances once some is expanded. In case with module-level variable you may end some dropdown closes some instances - but not all - just if you got few versions of the same package used(like coming as 2nd level dependency)
No access, and no isolation - hard to unit-test.
And finally: what could be a profit here?

need help for prev and next button in react

How to call back the effect operation when clicking the prev button using method or function with fullcalendar4 in react?
At present, I can only think of this way:
componentDidMount(){
document.querySelector('.fc-prev-button').addEventListener('click', e => {console.log(e)})
}
componentDidMount(){
document.querySelector('.fc-prev-button').addEventListener('click', e => {console.log(e)})
}
Looks like it works with React. Have you read some docs here about callbacks, or here specifically working with react and the underlying calendar's ref?
I've created a simple code sandbox that uses the callback style you try, and also using the API. Between the two, your method seems less recommended, but IMO is a little cleaner as it uses all the existing in-place UI, but is susceptible to being a little more brittle as the class names could potentially change, whereas using the API for next/prev these are calling methods directly so less likely to change.
I guess it depends a lot on what exactly you're trying to accomplish here, but what you have will "piggyback" off the button click, so if you're just trying to do something on the side it'll work.

Can I call an event handler with a parameter using inline declaration of the parameter without having the function be recreated on every render?

As I have understood it the following way to call an event handler is
+ compact and simple to read
-, but causes a new myWrapperFunc function to be created on every render
However, creating functions is cheap right? That that minus is insignificant, right?
Am I correct in my understanding that this way to pass an event handler with a parameter will not cause a new handler instance to be created on each render?
handler(event, val) {
...
}
<Component onClick={myWrapperFunc = (e) => handler(e, "myVal")}>
First of all, you are passing the function wrong. It should be:
<Component onClick={(e) => handler(e, "myVal")}>
If we talk about the main question, I'm not an expert but there is still not an agreement on this subject. There is a reality that your callback function is created in every render and this causes a performance loss. But how significant is this loss? This depends on your app probably.
Is it a big app which includes so many components that create callbacks like that. So, you should consider an optimization then. Some people say if you don't need optimization then don't bother with it :) Some says follow the best practices.
You can pass parameters to your functions without using them like that but somehow you should get these parameters in your component. If it is a prop then use it directly instead of passing it like that for example. Then use a separate function and its reference. You don't need to pass e for a callback, it is passed by automatically with callbacks.
handler () => {
use(event);
use(props.val);
use(val_variable_in_component;
...
}
..
<Component onClick={handler}>

Resources