Can React class components and functional components access the same context? - reactjs

I am working on a React project that was built primarily using React Class Components. Recently, the team decided to begin pivoting to functional components with hooks.
Is there a way for functional and class components to access the same contexts? In other words, if I have a context provider that is set up as a class/consumed by class components, can I then use a down-stream functional component to access and update that context?
The same question goes the other way (setting up provider to use useContext() hook and accessing it through a class component)
I have seen a lot online about "how to use context api," but have yet to see one that combines them instead of simply explaining the two ways to use context.

You can still use context in class based components.
Better still, just turn the particular component you're trying to refractor to a function based component.
Doesn't necessarily mean to rewrite the code.. just change things like the the class to const and the name of the component.
Next remove the render method and leave only the return.
Every other thing like the creating functions can be done above the return and inside the component body like regular functions.

Related

What is the best way to create a class instance variable only once in a React functional component?

I have a class instance variable that I create using new operator. I want this to be created only once throughout the lifecycle of a React functional component.
Should I create it outside the component or inside useEffect or use useMemo or some other way?
I think the best way to implement this would be to setup a context to store the var and then access/initialize it in the component.
Alternatively, you can also use a singleton via this package for example : react-singleton-hook . It's less "react standard" but singleton being a well known design pattern, it may be more readable and maintainable.

React. Functional vs class components

Is it possible to use both Functional and Class Components in a single React App?. I am building a website UI with React, back end has been build with NodeJS. The templates I am using was build with Class Components where they new Components I am introducing are Functional with Context API's. Can they work together or is it necessary I convert all the Class Components to Functions?.
Yes, you can use both in the same app. They are 100% compatible.
Each one can pass props to the other
They will be both compiled into plain javascript.
Quote from reactjs.org :
In React apps, whether a component is stateful or stateless is
considered an implementation detail of the component that may change
over time. You can use stateless components inside stateful
components, and vice versa.
Another quote from here :
"Crucially, Hooks work side-by-side with existing code so you can
adopt them gradually. There is no rush to migrate to Hooks. We
recommend avoiding any “big rewrites”, especially for existing,
complex class components. It takes a bit of a mindshift to start
“thinking in Hooks”. In our experience, it’s best to practice using
Hooks in new and non-critical components first, and ensure that
everybody on your team feels comfortable with them."

Hooks equivalent of container components in React Redux

I am new to using react hooks api.
Earlier I used to distinguish container components and presentational components.
The project directory structure was according to this distinction.
Container components used to inject store state and action creators to the component through props.
With hooks I have been left clueless how the directory structure should be and whether the hooks should be injected to the component through props or simply imported inside the component.
Should there be a containers and components distinction.
The redux documentation which describes container and presentational components also doesn't seem to be updated for hooks.
Any relevant article or answer is welcome.
About the separation between container components and presentational components, Dan Abramov (working on ReactJs, co-author of Redux and Create React App) wrote this in Presentational and Container Components :
Update from 2019: I wrote this article a long time ago and my views have since evolved. In particular, I don’t suggest splitting your components like this anymore. If you find it natural in your codebase, this pattern can be handy. But I’ve seen it enforced without any necessity and with almost dogmatic fervor far too many times. The main reason I found it useful was because it let me separate complex stateful logic from other aspects of the component. Hooks let me do the same thing without an arbitrary division. This text is left intact for historical reasons but don’t take it too seriously.
As user adel commented, there is now hook equivalents of react-redux stuff. To read redux state, instead of connect, you can use useSelector.
import { useSelector } from 'react-redux'
..
const somePieceOfData = useSelector( state => state.path.to.data )
About container components, you can still seperate your container, using react-redux hook stuff. There is nothing about that with react-redux.
I am also running into the same problem now and was looking for some nice resources in that , but here what I've reached:
There is no big need for the distinction now between UI and container components, you can use custom hooks for the same purpose and you will have fewer lines of code and more readable one. From what I've read (i didn't experiment this yet) but it should have better performance as using functional components including custom hooks inc the app performance.
Take a look at this :
https://dev.to/jenc/discuss-react-hooks-and-life-after-the-container-component-pattern-5bn

what's the best way to share user data between components?

I have a query i.e:
query me {
me {
username
email
}
}
now I need to share this data between components.
I guess I can:
create HOC withUserData and wrap other components
create a render prop component and wrap other components jsx
else?
It depends on where are places you want to share them, I mean if you want to share data in the same branch of the component tree, you can have a Container Component at the top ( Which holds your state and pass the data has props to the levels below).
If your components branch is very complex and it needs to travel down many levels then its a pain and not recommended too, in this case, consider using Context API
https://reactjs.org/docs/context.html
I would not recommend a HOC for this, HOC is not meant to share data, its meant to share re-useable functionalities.
Please check this, this has a bunch of best practices https://www.toptal.com/react/tips-and-practices
Well REDUX is another way but I would not recommend using REDUX looking at your need.
When to use REDUX?
Basically, you need to be using REDUX, when keeping the state in a top-level root component is no longer sufficient, like for example : ( you have two branches out from root component, one of the child components in branch A wants to access some state in branch B's child, then you need to move it to the root component and again pass it down, such cases are apt for REDUX ).
HOCs and Render props are not something that you would use to share data among components since each wrapper will have a different instance of the data whenever you create a component like
const MyComponentWithData = withUserData(MyComponent);
You would use HOCs and Render props mostly to provide a functionality which can be relevant to more than one components like detecting click outside of the component, or a PrivateRoute for authentication and so on.
However in order to share data you have options to use React Context, Flux or Redux. With the usage of React redux you can keep data in a store and read and update data from the components that want access to it. However if your app is not using Redux and you would want to share data only for a part of the application, you can simply make use of React Context. For more details on how to use it, you can read about it here

React-redux connect: root component connect vs multiple connects [duplicate]

I am new to react and redux. I have a scenario where there are nested components like this.
A > B > C > D
There is a property used in A component and it will be used in D component. So, I have two approaches:
Get state from redux store in component A and then pass it along as props to all it's child components even though it will be used only in D component.
I should connect to redux store in component D and fetch that property from there.
What is the correct approach?
As Dan Abramov, author of redux says in this issue
Both approaches of passing props down to children or connecting them
to the store are appropriate, however having nested connect()
components is actually going to give you more performance. The
downside is they're slightly more coupled to the application and
slightly harder to test, but that may not be a big issue.
He has also articulated a nice rule of thumb to follow on reddit
I do it this way:
Start by using one container and several presentational components
As presentational component tree grows, “middle” components start to pass too many props down
At this point, I wrap some leaf components into containers so that “middle” components don’t need to accept and pass down props that are
completely unrelated to them
Repeat
He has even tweeted regarding this:
Try to keep your presentation components separate. Create container
components by connecting them when it’s convenient.Whenever you feel like you’re duplicating code in parent components to provide data for same kinds of children, time to extract a container.
So in simple words:
You can use connect() at any level. Doing so makes the component smart, since it knows where its props come from. A dumb component just has props, and they could come from anywhere. A smart component is coupled to redux; a dumb component is not.
UPDATE: react-redux v7 and above
The same concept applies to useSelectors too. You can receive data in a container component and pass on to your presentational components, if multiple of its children make use of the same data
If however the data used by the children is different, you can choose to use useSelector individually within the child component. This will make sure that only those components re-render which actually need to
I would suggest if you are already using redux in your app then set the property in the redux store and fetch it in the component D.
But if the work flow is really simple and all the data is fetched from a single source per view, you can avoid redux as it is for complex state management.

Resources