I am experimenting with the useReducer hook in React
here is my following code in sandbox:
https://codesandbox.io/s/usedispatch-users-c58t4?file=/src/App.js
I create a user object with an empty array called interests. The array is initially empty and I have a form to add interests into the array per every instance of a user. This can be found in my 'User' component
in my reducer function with the case of 'ADD_INTEREST' I'm having a hard time understanding why I have to re-assign all the current user values with my action.payload before I add an interest into my interests array. I have been messing around for a bit and I can't seem to get it to work without having those values there. I know I'm missing something somewhere. Any feedback would be much appreciated. Thanks
Related
I wish to update particular input value, I suceeded to do so with one dimensional array but unfortunatelly in my case 2d is necessary and I have no idea how to do so as I tried already all combinations of rows and cells.
Here is link to demo -> https://codesandbox.io/s/stoic-mirzakhani-46exz?file=/src/App.js
Basically, thing is that after typing some value to for example X-axis in first row, I wish only this field value to be updated. I have button which can add new row to inputValue which contains all input titles, and contents.
Another thing is that if I write something to the input now, it transforms aray into object and because of that app crash
Alright, so you had a few issues going on here, but overall it was a good effort!
You were attempting to update the state directly instead of using the mutation function provided by array destruction and hooks
In the state update, you were not merging objects properly leading to the same value to be passed
You were not using props properly
To address these I made a new input component that tracks each component row and col inside its props. Then these values will be used alongside the prop drilled mutation function and retrieved content value from your chunk component.
Please let me know if this is not working
Below is a link to the working version, please look at the console to see the updates and there is a button that will print the current value of inputValue for you as well. State now also updates as you enter.
Edit: I have addressed your comment and fixed the example so that it follows your request. I went ahead and switched to using the useReducer hook instead now as it makes the logic a little easier to understand and to read in my opinion. Feel free to try to figure it out with useState too, if you wanted to do that. For now, though here is the link again: https://codesandbox.io/s/prod-resonance-wokey?fontsize=14&hidenavigation=1&theme=dark
I was always wondering if I should use redux store all the time even when it's not really necessary.
For example:
I have form with select field that has some options I fetch from API. Let's imagine that form is for adding new car listing and select options are car models. Should I directly call API from component and display options or should I create store CarModels or something like that and store results from API there and then map those values to state in component?
I have "Favorites" feature, when you click heart next to some item (let's say a car), do I need to go through dispatching all events FAVORITE_CAR_REQUEST, FAVORITE_CAR_SUCCESS etc... or is it good enough to just call API directly from component (using some kind of api-service of course).
It's related to question above. If I have screen where I show favorites, I should then probably have store and connect everything with actual favorite action so I update the list. On new favorite, API will return favorited item, should I push that one in list of favorites already in store or should I just load again latest list when user opens up the favorites screen?
Thanks in advance.
I think this is a perfectly valid question. What I feel like you're trying to ask is if you could/should mix react state and the redux store. The answer is sure! Just think about where you need to use that part of state before deciding where to store it. If you need a part of the state in multiple components, it probably makes sense to use Redux. If you only need state locally, perhaps to set form validation errors, maybe use react's state management if you feel like it. React and redux are both meant to be flexible, so as long as you're consistent in when you use the redux store and react state you should be good.
I found this article that also explains this pretty well: https://blog.jakoblind.no/is-using-a-mix-of-redux-state-and-react-local-component-state-ok/
I tend to use redux when the state has to be accessed globally / complex logic that i want to be logged properly
I working on my web app
I set there a store with react redux,
I have a form with 4 input type number which after pressing a button dispatching to the store as an array, then I have some others inputs that I’d like to get a value of the first 4 as a placeholders but when I change the value it should update the right place in the store , here is my problem , when I change its value (by typing) it change all the values in all the arrays connected in the store
It’s like the store works both sides , is there way to stop it ?
Thank you
It's hard to tell what your exact problem is without any code, but it sounds to me like you are overwriting the whole state of your array. Again, I can't be sure without code, but my suggestion is you spread existing state, and add your new array or whatever it is to the end in your reducer where that action is defined.
return [...state, action.newData]
For my client I'm creating something like quiz web app in react with redux based on websockets (socket.io) with a huge, very unique data. No user interaction, just presentation layer. It works like this: I get websocket event with url to my layout and payload data, and then I render given url and fire redux action with data as argument, which becomes app's state. Simple as that. BUT I noticed that on first render initial state is loading, not given from websocket as argument to action. As I said data I get is huge and unique so I didn't want declare in reducer something like this:
pageData: {
assets: [],
questions: [],
details: []
And so on. It's much more complicated btw it's just an example. Instead of this I made something like this:
pageData: {}
And I was hoping that on view (using connect) I can get this data like this:
this.props.view.pageData.questions
But then it turned out that I can not get this because it's undefined on first render. So my questions are:
Is there a way to access to this data on first render without
declaring whole structure?
If not, should I reconstruct given data in reducer?
Should I then create reducers for each page (there are like over 20 views
with unique data)
Of course I can declare everything in reducers but I feel it's very hard to maintain so much data.
But you know, maybe I'm just too lazy and I should declare initial state for each page and this question does not have sense ;).
I think you may have a few options here:
Define fallback data in your components if undefined
Don't render your page (or components) until you have received the data
Define your initialState explicitly as you already suggested
All or most your components expect or should expect data of a certain kind and in a certain format. For this reason, laying out the structure beforehand (#3) seems to be most appropriate. Ask yourself this: would my app still display correctly if the format of the web socket event data changes?
To answer your questions specifically:
Is there a way to access to this data on first render without
declaring whole structure?
Yes, you could use the || operator in your bindings to fall back (#1) to an empty array or object or value. Example <MyComponent listOfItems={this.props.items || []}. This effectively creates an empty state, however, IMO this should be standardized in the reducer/store with initialState.
Should I then create reducers for each page[?]
Not necessarily a reducer for each page, but a store with all pertinent data to your application. It is hard to say for sure without knowing more about the architecture of your app, but keeping small, well defined chunks of information is generally easier than one big blob.
I strongly advocate defining your data beforehand. It might sound cumbersome at first, but it will pay off greatly and helps others understand what the app might look like with live data.
that's because you haven't added default case in reducer
default:
return state;
I have two context types: (1) productsContexts & (2) rangeContext.
rangeContext is nothing more than preset ranges from a json file so as to group the products according to each respective range.
Below is an illustration of a side-box component that groups products
according to those preset ranges and it also illustrates the problem:
The first visit to that page, everything works fine, but click off and then re-visit the page and the previous data remains and then doubles itself, 3rd time, it is triple, and so on.
I did nothing with the rangeContext data but pass it along to a local variable for mapping data manipulation. I did not save anything to the context itself.
Here is what I have tried to do to solve this problem; all have failed:
I passed the rangeContext to state first, then on componentWillUnmount, I initialized state.
I Object.assign() the rangeContext to the local variable instead of directly passing the context to the local variable.
I took the context completely out of this component and used it in it's parent, and passed it to this component as props.
Nothing is working. While the hard data does not change, the range component never gets initialized on unmount and revisiting the page just carries forward what was in the range in the last visit and adds to it.
I know I probably did not do a great job explaining, but I know the problem is related to the context and I sure do not want to hit the database again, as I already did that for an earlier component.
Does anyone recognize the problem and have a solution?
Thanks
UPDATE:
I moved contextTypes for ranges out of the side-box component.
Using redux flux, I dispatched for the range-actions in side-box's parent and passed the ranges to side-box as props. The problem went away, but I am not happy. I need someone to tell me why this is the right things to do, as ...
I had already called range-actions in a previous component, so why not put it in contextTypes instead of calling redux again?
Where as I only had 3 lines of code on side box, I have the same amount of code lines since now I am calling propTypes, but now I also have
MORE LINES of code in the parent calling redux, something I had already done for the range data in a previous component.
I would greatly appreciate someone telling me if I am still doing this
all wrong, or why it is right I had to add 26 more REDUNDANT lines of
code calling redux flux?