I have a problem. I have an example1.js file that fetches data from DB in options. when I select the option data shown in table form.
when I click on the button to mark attendance it goes to another component e.g example2.js with param. but when I go back it must be in the same selected option. Anyone can help me. Code for go back is the following I am using.
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
const goback= () => { navigate(-1) };
You can use redux or for going back you can simply use the in built js function of history i.e history.back()
I highly recommend you to use Redux store for this: https://redux.js.org/
Using Redux(recommended approach). You can create your own state and write reducer to handle/set/change state.
In your component when you would like to receive the state you can use useSelector hook or connect, if want to change your state, use useDispatch, please read how to create a store and usage of hooks related to Redux: https://react-redux.js.org/api/hooks
Using context(not recommended for your purposes because it is not designed for high-performance/many actions. But it is easier to setup/use if you don't need a Redux).
Please read about context: https://reactjs.org/docs/context.html
All in all, you need to preserve your state 'somewhere' in Redux or Context to prevent refreshing the data while navigating/rerendering the component.
I you are not comfortable to use redux then try to use react reducers and context api together to create redux like structure. It helps maintaining states between different routes even on navigation.
You can refer these link.
https://hmh.engineering/using-react-contextapi-usereducer-as-a-replacement-of-redux-as-a-state-management-architecture-336452b2930e
https://blog.logrocket.com/react-hooks-context-redux-state-management/
Related
I have an app with react-router-dom and use the BrowserRouter component. In the app, I have route /query-builder that will essentially build a query string through picking values from tables etc. Once the user has the query string built, they can navigate to /search?q=<some querystring> via the useHistory() hook from react-router-dom and history.push('/search?q=${queryString}').
What I would like to know, is it possible to navigate back to the /query-builder route, via the browser back button, and see the page as it was just before I navigated to /search so the user could make amendments to the query. What I am seeing at the moment, is that the query-builder component will go back to its initial state, as it is mounting again.
I could use redux to manage the query builder state and rehydrate the components from that, but I am wondering am I missing something available in the react-router / react-router-dom packages?
Look like useContext is best variant to solve your problem. Save variables in query-builder, then you can easily go back without any scare) Also it'll work properly both in history.goBack() and browser back
I am developing a desktop app with react for UI and electron.
So, for now, I am fetching data from the server and saving it in the state using React's Context API to update the UI.
I am keeping the state and the function to add, remove and update state in the renderer process and with IPC I am sharing the data between renderer process through main process (as it should be).
But as the application is scaling I need a better approach. Something like a central state (if that's a thing).
P.S. can I use a database along with the Electron app if there is any real-time database such as rxdb?
I had this exact same problem and I used electron-redux (https://github.com/hardchor/electron-redux).
I was also using react for my UI.
I ran into the same situation where I needed a single redux store for all my react renderer process in electron.
I tried electron-redux but that did not work for me as react complains about the snippet of code you need to put in the renderer process.
nice solution:
After some search I ran into redux-state-sync which is a redux middleware that used to synchronize the redux store and actions across multiple react tabs, which works nicely with electron as the tabs here are the different renderer process.
The only hindrance is to initialize the store in the newly created window, that can be done by sending the store state with an ipc call from the main window that opens the new one, that dispatches an action to update the state.
This initialization approach works nicely in react#17.0.0 , but for some reason it doesn't in react react#18.0.0
The best way to have a 'master state' is to use React-Redux.
Redux can do what Context does and more. It also has lots of libraries for listening for realtime updates from servers. The most popular at the time is React-Redux-Firebase, which connects your Redux store with your Firebase database.
Most developers agree on the fact that Redux takes some time to set up, but is definitely worth the time invested. I have personally used React-Redux-Firebase and I can assure you that all real-time updates will be in your Redux store within 250ms.
Firebase is also free up to a certain point (check Firebase Pricing).
In order to access your Redux state in a component, your need to follow 3 steps:
STEP 1: Create a mapStateToProps const that contains all the stuff you want from your store.
const mapStateToProps = state => ({
customers: state.customers,
books: state.books
})
STEP2: Create an actions const that contains any functions you have in an actions.js or similar file and you want to call
import { fetchCustomers } from './actions.js'
const actions = {
fetchCustomers
}
Remember that any fetching from your API can (and should) be done from there.
STEP 3: Export your component with Redux's connect function, including your mapStateToProps and actions consts.
export default connect(mapStateToProps, actions)(myComponent);
Redux is rather complicated to be explained in a single stackoverflow answer, so I suggest you take a look at the docs or follow a tutorial. You should be able to figure everything out in your first or second day of development. It is absolutely worth the time.
I working on a webshop in Vue js, and when i add products i use event bus and then i add the products to the CartComponent by event bus. And its working, but when i go back and add a new product or just go back so the page reload all the data in my CartComponent is deleted. How can i do so its never delete the data it got?
I have tried to surround the component with
<keep-alive>
<CartComponent />
</keep-alive>
But thats not working.
Can someone tell me how to do so the component not delete the data when i switch routes?
The bus is a communication hub, it does not store the information for you.
You have a couple of ways of tackling this:
implement your own module where you store this information. When you update the cart also update your module. Or
use Vuex, which as a store implementation. All your info should flow thru the store. It is persistent and globally available. More about Vuex here
I highly recommend using Vuex.
I'm trying to build a E-Commerce Store and it requires that I initially load a list of trending products on the home page.
Here, I can simply do without redux and simply display the data (roughly) of this sort
const trendingProducts = await get('/api/trendingProducts')
render(){
<TrendingProducts data={this.trendingProducts.data} />
}
I am using redux in my application. So should I do a dispatch elsewhere to fetch the trending products ?
All in all, Should I always handle every single fetch / render using only Redux dispatch ?
Redux is a store management for your application's state. Redux's dispatch is used to dispatching actions that aims to update your application's state in some way.
Hence if your application logic requires displaying information that belongs to your application's state - you need to take it from Redux store. If such information is not yet available into Redux store - you need to obtain it from some source (e.g. fetch) and use dispatch to update your application's state. If information, you're trying to display is not part of your application's state - you can display it directly, but in this case you'll need to handle React lifecycle events by yourself too since React re-draws components upon component's state change.
UPDATE: Your example code will work fine if you'll put your trendingProducts into component's state:
class MyComponent {
constructor() {
super();
this.state = {
trendingProducts: {}
}
}
componentWillMount() {
fetch('/api/trendingProducts').then(data => this.setState({trendingProducts: data}));
}
render() {
return (
<TrendingProducts data={this.state.trendingProducts}/>
)
}
}
That is very subjective and there is no correct answer but I can tell you by my experience.
Always keep your business logic separate from your component
If you're making API calls then you should definitely dispatch an action rather writing this in your component because there are lot of redux-like stores are emerging and it might happen that later you want to change your store using some different architecture. Your view layer should be independent on your API calls (business logic). In this way, while refactoring your app again, you'll just have to change the logic and your view will remain the same.
I'm writing this on my experience where we started refactoring the whole app from backbone to React. We had models and collections, we changed the whole html but we didn't change any business logic initially, just the views were deprecated but later we removed the business logic too using redux (iteratively). You should write your code in such a way that it has maximum reusability after all that's what React is and that's how you should write your front-end code.
Also, the component's state can reside in component where the whole app doesn't get affected. e.g. showing or hiding of a third-pane or overlay etc.
I'm starting to develop an app that will be making calls to an API that will require the inclusion of a JWT that I plan on storing within the Redux store.
Typically you can access the Redux store by mapping a particular part of the store to a component's state with mapStateToProps() and connect(), however I'd like to access the Redux store within a file that will not end up being a React component/container - just a pure js file that will be handling the API calls.
Is this possible?
You can use the getState() function of the store returned by createStore. You can use this inside a function that fishes the needed data from the state.
const myImportantData = () => store.getState().my.deep.data;
The version above uses the store directly, as in a global variable. This prevents you from using more than one store in your process. Normally this is what you want, but this isn't true when running on the server. That said, on the server you'll likely not need the JWT access anyway.
If you do need to swap stores, however, then you can pass it as a parameter or close over a store local variable:
const getDataGrabber = store => () => store.getState().my.deep.data;
Yes, it is possible.
Redux is framework agnostic, although it was made with React in mind.
The mapStateToProps() and connect() methods aren't part of the core Redux library but of the helper library 'React-Redux' which provide bindings specifically for Redux use within React.
It's worth checking out Dan Abramov's Getting started with Redux series to get the principle of how the guts of Redux works.
An example of which are Video 6 and Video 7 where he discusses the Redux store and describes the three methods that make it up:
store.getState // gets the current application state
store.dispatch // changes the current application state by dispatching an action
store.subscribe // suscribes to changes and re-renders the app using the
// current state
The videos go into a fair bit of detail as to how to register the reducers with the store, so the series should prove very helpful.