useRef Did not change the element style in React - reactjs

okay i am trying to make a toggle display element from hidden to block and vice versa and bind it to a button.
i use useRef and it somewhat work, but only one time, it doesn't toggle again after the element display is block.
here is the code i use.
const handleMobileMenu = () => {
setIsPressed(!isPressed);
const state = isPressed ? "flex" : "hidden";
mobileMenu.current.style.display = state;
console.log(state);
};
the console log displaying what i want which is block, hidden, block, hidden.. its toggling. but the element doesn't.
i've tried using, if else, but same problem.

yup silly me, just use a conditional className, and the problem is solved.
thanks Dennis Vash

Related

IntersectionObserver Flickering with ScrollIntoView

I'm trying to build a custom input that you can change its value by scrolling with IntersectionObserver and ScrollIntoView
The problem that I'm facing is that when I try to make the component controlled with a state it starts to flicker when scrolling.
I have the example here in this sandbox, and you can see the input gets initialized correctly with the correct value, but when you try to change it.. there is a flickering at the beginning of the scroll event. also resetting the input by the button does seem to work correctly.
I'm not really able to figure out how to get the updates correctly done in each event since I'm very new to Intersection observer
Try setting the threshold value to 1 such that it will fire only when it goes out of boundary completely.
const observer = new IntersectionObserver(
(entries) => {
const selectedEntry = entries.find(
(e) => Number.parseFloat(e.target.textContent) === value
);
selectedEntry?.target?.scrollIntoView();
entries.forEach((entry) => {
if (!entry.isIntersecting) {
return;
}
!isFirstRender &&
onChange(Number.parseFloat(entry.target.textContent));
});
},
{ threshold: 1 } // changed to 1
);
Also please do as the linter says, and add proper dependencies for the useEffect hook unless when not needed.
If you are using React, you might consider react-intersection-observer.
In my case, I was able to remove flickering by setting option triggerOnce: true.

Best way of closing custom React dropdown?

I know two ways of closing dropdown:
Listen for clicks and if target is not dropdown - close it.
Create transparent backdrop, with onClick event that will close dropdown.
I want to know which one of them is better in terms of performance? Something tells me that it should be second option, since we don't constantly listen for clicks. But everywhere I look in online examples, first option is mostly used, which made me curious in reason behind it?
This is not a question for opinion, but rather I'm interested in performance and possible issues of each method.
Best approach would be to listen to click events on window object and toggle the a state variable. It's more simpler than creating a transparent backdrop.
const [active, setActive] = useState(false);
const outsideClick = useCallback((e) => {
if (active) {
setActive(false);
}
});
useEffect(() => {
window.addEventListener("click", outsideClick);
return () => {
window.removeEventListener("click", outsideClick);
};
});
In case there are situations, like a complex dropdown where sometimes clicking inside the drop container we don't want to hide the menu, you can do some additional checks like, inside the click handler -
e.target !== selectCategory.current.children[0]
Some examples on codesandbox - #1, #2

Why does using React Context with Framer Motion not work?

I have a version of a slideshow where the state is being stored locally, you can see that the slideshow works great and the slide components only are unmounted once the animation is complete. https://stackblitz.com/edit/react-framer-motion-slideshow-official?file=src%2FSlideShow.js
Once I added the context to handle the values, the animation sliding still works but the exiting component is replaced with the new slide content when the animation begins, which looks really strange. Also the custom value for the slide directions seems to be broken. https://stackblitz.com/edit/react-framer-motion-slideshow-official-context?file=src%2FSlideShow.js
Do you have any ideas how I can get the animation to work correctly again when using context?
Everything that consumes a context re-renders every time that context’s state changes. So the children of your Slides component
rerender
see that the new variant = to the next state
appear at the destination
If I were you I wouldn't use context. If you really want to not explicitly pass the same props over and over you can do
{[
MainSettingsSlide,
ChangeLanguageSlide,
LanguageDetailsSlide,
BlockedSitesSlide
].map((Component, i) => (
<Component
activeSlideName={activeSlideName}
onNavigateSidebar={onNavigateSidebar}
key={i}
/>
))}
Sorry for the indirect answer :)
Edit two days later
In rereading your question I realize there are some other problems
You need to always conditionally render based on props not context
const Slide = ({ children, slideName, className, activeSlideName }) => {
// This context will update outside of framer-motion
// framer-motion animating something in while it is animating something out is
// predicated on you giving it control by using props
// const { activeSlideName } = useSlideShowContext();
// console.log('activeSlideName in Slide', activeSlideName);
// console.log('---------------------');
if (activeSlideName !== slideName) {
return null;
}
Your onNavigateSlideShow was using slideDirection instead of direction
const onNavigateSlideShow = ({ slide, direction = 'forward' }) => {
// const onNavigateSlideShow = ({ slide, slideDirection = 'forward' }) => {
console.log('ccc', direction);
setActiveSlide([slide, direction]);
};
I still can't get the directions to go in the right direction
I think this is due to a race condition between the direction being set and when the animation is kicked off
If you click the back button before the animation completes it works as expected.
Here is where I got to: https://stackblitz.com/edit/react-framer-motion-slideshow-official-context-dftoab?file=src/SlideShow.js
Sorry that this is again not a complete answer. I think I am coming to the same conclusion as before that the two apis probably shouldn't be mixed. Especially due to edge cases like this one.
There have been a decent number of questions recently about context and AnimatePresence so made sandbox for most of the cases that I could think of: https://codesandbox.io/s/framer-motion-using-context-with-animate-presensce-nuj0m

react-hook-form reset errors messages only

I have some dynamic fields, which gets removed/added on the basis of some hook state. I have fields which gets removed from the list but the errors for them are still visible. I have tried to clearErrors, unregister to remove it but nothing works.
is it possible? reset does work but it resets the whole form too.
I am using v6 of react-hook-form and i cannot upgrade it to 7. That's out of the picture for now.
yup validator is being used with it for validations.
I stuck into the same problem seems like bug, if you try unregister the control it doesn't do it. Here how I have done.
When you remove the control do unregister and reset specific control.
const handleRemoveRow = (control) => {
//all code logic and stuff
//................
unregister(control);
reset({ [control]: undefined });
};
After that on useEffect hook assume you have one main state of form, reassign the values back.
useEffect(() => {
const keyValue = getValues();
keyValues.map(({controlName,Value}) => {
setValue(controlName, Value);
});
}, [getValues()]);
This is a more of pseudo-code but I hope you got the concept.

Framer / React: Can't change focus state of Text Input onClick / onChangePage

This is a Framer/React question:
I have a bunch of text fields in a "page" component and I want the focus to shift on every "page" change.
There's a button controlling the pager but no trigger (onPageChange / onClick) is changing the attribute of "focus" on the relevant text input.
This is the code I tried using to change the value of foc2 (the focus attribute) to true
When I manually change it to true it works, but in this case it doesn't
export function Page(): Override {
return {
currentPage: state.page,
onChangePage: (index) => {
state.page = index
state.foc2 = true
},
}
}
Do you have more complete code you could share?
Make sure you set the state to the index of the current focused input, and use that to change the currentPage property.
Happy to help if you send more context, you can also find more help in Framer's community at https://framer.com/r/discord

Resources