React - Approach for changing theme - javascript

I am using the React library, I want to add the ability to change the theme, it will look quite simple there are three buttons (or radio buttons) and when you click on one of these buttons the picture will change, the problem is the implementation and updating the page (so that the image does not disappear) I want to ask about implementation, how can I implement it? create a state and inside a state create imported names that each of them stores the picture itself? or it's a bad idea, and at the end I wanted to know how to do it so that when the page is refreshed, the picture does not disappear after changing the theme

I suggest using React Context, you would wrap your whole app in a ThemeProvider, then any component that needs to react to changes in the theme can access the current themeName value via the useContext hook. Here is a freecode blog on how to achieve what your after, using Context and CSS modules.
Just to note, this solution will not persist page refreshing, but the 2 solutions could be combined, if that is necessary. So when you change the theme, localstorage is also updated with the current theme name. On page load, you could read the theme name to configure the Context.

Related

How to implement a generic react native backdrop?

I want to create a generic component that should detect required component View outside click (hide the View/dropdown, etc. when pressed outside). Basically it's for the Autocomplete Search Dropdown but I guess such functionality could be used in the future for other things.
The content should be dynamic and could be passed from any level of the app because such functionality is a common UX thing.
It shouldn't be modal that always render content at the screen center because a dropdown should be opened below its trigger, etc. So it should respect the initial component position. (In think to use onLayout/measure API of the initial position when passing the content into the Backdrop)
I researched a lot of resources and found that the one possible way is:
Create a TouchableWithoutFeedback layer (Backdrop) at the top level of the app.
make it fullscreen with/height
When dropdown is shown: render the Backdrop and onPress on it - close the dropdown & backdrop.
The main question is: How to pass a generic content into this Layer and save its relationship with the parent/props, re-render when needed, etc.?
Please, keep in mind, that the component which should pass content for this layer could be deep inside the app.
I guess it could be done via Context API, etc. but I'm not sure if it's the best possible way.
P.S. in the case of web it's a trivial task: create a fullscreen layer -> use a portal -> move content at the top level of the app -> render it at the required X\Y position and listen for the outside press.
I didn't expect that such functionality will be a problem in the case of RN.
Thanks for any help.

Call method from sibling component using ReactJS

I have one ReactJS App which I reduced to the minimum as possible on the diagram below:
Side note: On this App I use Redux to manage state changes.
This App contains:
Component: UploadScreen with an image holder and a button. When that button is clicked, the user gets displayed a Popup Window which let him to pick an image from his device file system. Then that image is displayed on the image holder.
Component: AuxWidget which is a totally different component (needs to be separate) which also contains a button that when it is clicked it should popup the Select File window. I was thinking in something like triggering the click event of the first button.
Any idea on how to achieve that?
First I though about using Redux but I think that's not a too good idea because even though you can send messages with it from one component to another, that causes a render update and I don't want that.
Also, I was thinking on using jQuery but that's not the best approach when it comes to ReactJS.
Also, I thought about using the attribute: ref="foo" to get a reference to the other component but I think that's normally done when you want the interaction to be between parent and child components.
Also, I was thinking about EventEmmitter but I don't know if that's the best approach on this case (I'm using Redux to manage the state changes between components).
One of the best ways I can suggest using RxJS, you can create a Subject and pass it to your components. In one component you will need to subscribe to it and whenever you will call next on your subject from the second component, the other will be notified, so you can trigger open popup. You can even create your own implementation for this in case you don't want to add new library to your project.
The upload window could be triggered when a certain state in the app changes. The relevant state on the app could be changed from different places, like from AuxWidget and UploadScreen. That way they are not coupled with the upload window. They merely call a function that is passed to them and that function changes the state on the app and it will display the window.
If you have a shared component between two unrelated component I think it is best to lift that common component and let its state sit on a higher level.
If I understand things correctly, your primary concern is code-reuse as opposed to wanting to call a sibling method. Basically, you want a SelectFilePopup component that can be re-used (open/closed) cleanly. I think React Portals could be a good solution for this. I found a good example (https://github.com/Assortment/react-modal-component/blob/master/src/components/Modal.js) of how a Modal can be isolated into a component and be called anywhere in the codebase.
The usage of the Modal looks like this (copied and slightly modified from App.js in the github project above)
import Modal from './components/Modal';
<Modal><div>Click me to open Modal</div></Modal>
And the Modal component implementation (simplified)
render() {
return (
<Fragment>
<ModalTrigger
onOpen={this.onOpen}
/>
{isOpen &&
<ModalContent/>
}
</Fragment>
)
}
By default the Modal component shows a trigger (i.e button) when isOpen state is false. Once clicked, and isOpen switches to true, the ModalContent (i.e can be the FilePickerPopup) is dynamically created and attached to document body. You can check out the source code for more details. I think its a very clean solution to modals. So in your case, your code could end up looking something like this
UploadScreen.js
import FileSelectPopup from './components/FileSelectPopup';
<FileSelectPopup>{Upload Image}</FileSelectPopup>
AuxWidget.js
import FileSelectPopup from './components/FileSelectPopup';
<FileSelectPopup>{Upload Image or some other text}</FileSelectPopup>
So basically, AuxWidget doesn't even need to know about where the FileSelectPopup is located at. It's an independent component that can be called anywhere. The caveat is that the Modal implementation in the project I linked to is not a singleton (although it can be modified to be one). So if AuxWidget and UploadScreen are visible to the user at the same time, clicking both Upload Image buttons will create two instances of the Popup.
I would define the function in the parent component and pass it to both children as props

trigger save mutation from outside of multiple Apollo React components

In suite of React apps we're placing per view set of reusable apollo-backed form components with just one save button placed outside of the form components. On a save button clicked each component (with dirty state) should execute the mutation to persist changes.
I wonder about possible implementation options and I would like to avoid using refs.
The problem to be solved seems to be - how to call a method outside of the component - I tried to follow on this question Call child method from parent and while I'd rather do not use any React way of communication between components, one particular answer that looks promising to me is https://stackoverflow.com/a/45582558/3021889 - still I'd like to hear what options do I have.

What constitutes an appropriate use of ref in React

Can someone explain how ref is used in React? I understand it's a shortcut that sort of defeats the purpose of the react DOM, but I don't know how or why exactly. I'm trying to determine whether something I'm trying to accomplish represents one of the rare cases where you should use ref
I want a custom bootstrap alert I can show from any of these pages, without using JQuery (I have one working with JQuery already)
I have a router that switches between pages, each containing a Layout component with a Page component inside (based on this)
Like:
render() {
return (<Layout ref={layout => (this.layout = layout)}>
<WhateverPage
session={this.session}
otherExampleProp={"something"}
showAlert={this.showAlert}/>
</Layout>);
}
showAlert(type, text, hasTimeout, timeoutMs) {
this.layout.alert.showAlert(type, text, hasTimeout, timeoutMs);
}
I can think of three solutions:
Use ref, which as I only partially understand defeats the purpose of react components to some extent, but I'm not sure how exactly...
Use ref, but to a lesser extent, by placing the alert component in each Layout before the Page component (so no need for a ref to ).
Create a component and a function on each page, using the page's state to control the alert, so it would be basically the same as creating a unique alert for each page, which also defeats the purpose of a component...
The example most people give when explaining what to use ref for involves focus() - is this similar? Intuitively it feels like I should use ref, but I also know that theoretically you shouldn't, but I want to understand why, because there are exceptions and for all I know this may count.
Similarly, I want to create a confirm component to replace the native JS confirm() (since it might be deprecated soon), and this approach (using ref) also makes this WAY easier than creating a component for each page, since I can pass any function as a parameter to the confirm component for it to execute on an OK button press (also gives me the option of including icons, titles, custom buttons, etc).
Existing examples and libraries all seem to use method 3 (or they're simpler, and not not really analogous).
Is ref ok to use here? Is it wrong? Why? Am I overthinking this?
Yes, you are "misusing" ref here because you're trying to build around how React is intended to be used.
ref is mainly for accessing the actual rendered DOM element - maybe to focus it, read input, get dimensions, whatever. Generally speaking though you should us ref as a "read only" feature - use it to get info about the rendered DOM but don't use it as part of a process to bypass render() or inject elements into the DOM.
What you should do is create a reusable component for your Alert. Make it flexible enough that it can accept arbitrary settings like color, text, duration, callback functions for accept/cancel/clear, etc. Then you can just render it somewhere, maybe like this:
<MyAlert
title="foo"
text="bar"
duration={5}
confirmCallback={someFunction}
cancelCallback={anotherFunction}
/>
Remember that components are a way to render and interact with state, and that's exactly what you're trying to do with your Alert. There is some kind of notification, it has content and controls for doing some action(s), and all of that should live somewhere in your app state hierarchy. There is absolutely no reason to resort to refin this situation.
To complement the jered answer:
If you plan to use the alert component in all the pages then instead of placing an alert component inside each page you can create a high order component named like PageWithAlert (I would say just Page) that includes the alert component for each page.
You might want to take a look at this https://facebook.github.io/react/docs/higher-order-components.html

Reload react-masonry-component manually

Used React Masonry Plugin for my alignment of cards https://github.com/eiriklv/react-masonry-component
Problem is I have expandable component in cards which increases the height of the card and masonry layout gets distorted. Plugin realigns if state of the data is update or it works on scroll. Any idea how to reload the layout manually on expandable content. Checked out issues on plugins also but didn't find an appropriate solution. Any other react wrapper pf masonry or plugin recommendations for this scenario? Thanks for help in advance
I know that using jQuery I can use reloadItems and layout methods but I am trying to avoid jquery
I was facing a similar issue in which I wanted to remasonrize (if you will) after each toggle show/hide of a div.
In my case I had component A as the parent (with the <Masonry> component)
and components B1,B2...Bn inside it.
Every time I toggle (in your case resize) either of B1,B2...Bn it would update the state of A thus causing the Masonry component to render again.
If you post your code sample then I could help you out with the exact code.
You can access the masonry component based, as explained in the documentation:
https://github.com/eiriklv/react-masonry-component#accessing-masonry-instance
and perform manual layout on the instance directly.
However it seems that the update should have happen automatically in react as you probably changing the state of the component to render it in the expanded mode.
So you might want to explore why the update is not happening for your case.

Categories