4 ms·
I’m going to hijack to request some help understanding whether hooks are a good thing or.... a mediocre thing I just have to accept. Here are my questions: 1)
by erikpukinskis 7y ago
I’m going to hijack to request some help understanding whether hooks are a good thing or.... a mediocre thing I just have to accept. Here are my questions:
1) Is it just me or so hooks really push you to commit to either “state comes from props” or “state is held internally” but you REALLY can’t mix the two?
So, if I have say, a searchable select box, I must either A) be stateless, and let some other part of the system store the user’s typing, or B) use a state hook, but NEVER react to state changes coming in from outside.
I.e. I am tempted to use useEffect to notice my props and my state being out of sync so I can sync them back up, allowing either the user or the backend to provide changes. But that also feels bonkers.
Doing the same thing through message passing also seems bonkers, React was created to replace having to pass messages around to every component that needs updates, wasn’t it?
2) Is there any point to useCallback? Is it literally the same thing as returning a function from useMemo?
3) Is it just me or is useRef kind of a horrible hack? Lots of articles tell me to do myRef.current = myState in order to hack around the fact that state changes don’t take effect until the next tick. But now we no longer have a single source of truth, and introduce lots of sync bugs. Also have to type .current everywhere.
4) Should I be using useEffect instead for solving the issue with #3?
I just have this sinking feeling that at least one of useRef, useMemo, useCallback, and useEffect shouldn’t exist, but I am only three months in to React and I can’t really see the forest through the trees.
- darcien 7y ago1) You could mix the two around. E.g. using a state hook and the imperative handle hook. By using the imperative handle, we could update the state from the outside by exposing the setState function. 2)There are several points, but I think the most important one is simply just to save time instead of using useMemo as passing callback to child components is pretty common. And yes, it is the same. The official docs literally said that. useCallback(fn, deps) is equivalent to useMemo(() => fn, deps). [0] 3)You can call it a hack I guess. If you don't want to wait for rerender, you can keep a value inside a ref! While class component can just create a property, function component doesn't have that. That's where the useRef came in, and that's just one use of useRef. I'm not really sure about the articles you mentioned. I never faced a use case where you would use a state and also keeping it inside a ref, can you share an example link maybe? For the .current part, since refs is originally used to access the DOM. And the DOM node could change for whatever reason. To access the node, we use .current. 4) It depends, but I don't think keeping two things in sync using useEffect hook is a good idea. I'm not really clear about the issue, so I can't say much. After using React for a while with class and lifecycle, I think all the available hooks is really nice. Feels like we got a fresh wind while developing with React. Using hooks and not have enough contrast to make me feel I can no longer code React without hooks. They let you reuse and share the same logic for different components or projects easily. Less code to read, and for me, functional component with hooks is way easier to read compared to a class component. Refs: [0] https://reactjs.org/docs/hooks-reference.html#usecallback https://reactjs.org/docs/hooks-reference.html#usecallback
- mpolichette 7y agoI have been doing React development for a good amount of time now and I really like what hooks allow. It does diverge a bit from classic OO ideas though, which can be tricky to wrap your head around the first time. Hooks do a good job of nudging you to make better decisions about how to design your app, primarily by making bad decisions harder to make. This feels bad initially but once you get it, I think its better. That said, lets address your issues: 1. Yes/No. There is no reason you cannot have both props and state effect your component, however I don't think thats your question. If you need something outside the component to effect what is typed into the box, (e.g. the app can clear the text) then yes, you should be passing the text in as a prop, along w/ an onChange callback prop for when the text is changed within the component. I think of it as, if the state can be changed somewhere else then it doesn't belong to the component, and is thus a prop. Note, the options could be filtered in the component or not, also up to you. 2. I agree with this question. The main use I've found of useCallback is to avoid triggering changes to other hooks. ¯\_(ツ)_/¯ I think react team members have even asked about how people use it: https://twitter.com/brian_d_vaughn/status/1174359975600091136 https://twitter.com/brian_d_vaughn/status/117435997560009113... 3. useRef is great. It allows you to store state which does not trigger re-renders. This gives you a finer detail control of your component. I would not use it to "hack around the fact that state changes don’t take effect until the next tick" though. I think it would be bad practice to have to think about when state changes take effect. (This might be one of the "making bad decisions harder to make" moments) P.S. I agree about typing .current everywhere, but it makes sense from a JS perspective. useRef is simply keeping track of an object instance and you are accessing a member of that object. I'm not sure if it has to be 'current' or if thats just convention (anyone know?). 4. I can't answer this without an example. Generally, if you need the value to render, you either have it via a prop or it it is already stored in state. If you need to transform that value in order for it to look right, you do that inside your function. If it is a complicated calculation, do it with useMemo, so it only has to be done if your value changes. If something causes your state to change, you should just update the value and then allow it to rerender, thus it becomes the already in state case. Those changes should really only be part of other actions though, not your render function itself. So that was long winded, but hopefully useful. I think hooks are good and generally use the following heuristic: - useState: state which causes rerenders on change - useRef: state which does not cause rerenders on change - useMemo: calculated state based on other props/state (only needed if the calculation is expensive) - useCallback: useMemo for functions :p - useEffect: Do something based on state or lifecycle of component (e.g. mount/unmount) (edited for formatting)
- manigandham 7y agoThis is a good guide for "thinking in hooks": https://wattenberger.com/blog/react-hooks https://wattenberger.com/blog/react-hooks You can combine whatever inputs you want, whether props or internal state variables. Hooks are basically a way to specific "do X whenever any of Y variables change", regardless of what those vars are.