Updating state in react hooks (adding new object) - reactjs

I'm stuck in updating states , I'm using a function for generalising a Modal from a 3rd party framework now when I want to update the particular variable I'm stuck as dynamically its not updating ,i.e: Ex: setModalState(...oldstate,v1:{v2:false}} . Here ${v1} and ${v2} are already in old state and I passed to function as props but javascript is not taking insted taking v1,v2;
I have attached few photos for understanding
https://res.cloudinary.com/df2q7cryi/image/upload/v1615998821/error3_svxlcw.png
https://res.cloudinary.com/df2q7cryi/image/upload/v1615998764/eroor2_enjcbc.png
https://res.cloudinary.com/df2q7cryi/image/upload/v1615998762/eroor_bz5wwf.png

Solution is to use | setModalState({...modalstate,[section]:{[purpose]:false}})}
Reference : https://stackoverflow.com/questions/9398535/add-dynamic-key-value-pairs-to-javascript-array-or-hash-table/9398583#:~:text=You%20need%20to%20define%20an,square%20bracket%20and%20dot%20notation.

Related

Using UseContext and UseState with MUI causing unknown bug

I’m working on a react app in which I want all of the user inputs to live inside a global json object. (This is a multi page form) This object lives inside the parent function (P) and uses useState (let’s call the functions obj and setObj). I wrap the children function with a useContext such that all children (a,b,c). <context.Provider>’s has value={{obj, setObj}}.
Function a grabs the context created in P and it consists:
Const {obj,setObj} = useContext(*context created in P*)
<TextField
…
OnChange= {((e)=>setObj((prev)=>({…prev, e.target.name: e.target.value}))}
name=“name”
Value = {obj[“name”]}
/>
(The syntax may be off here, but it works in my program.
The problem I have is that every time I try to type in the textField, it exits out of the textField (where I have to click the textField EVERYTIME to just type ONE character). I want to create a program where, if possible, children can update the obj in the global state as if the textField was in the same function.
I have implemented this in things like and components. It works perfectly, but I think it works here because those values are limited (To things like Y/N or elements in a list). I believe the error comes because we are always updating a variables from another function (which is what I want to happen).
Any suggestions would be of great help!
Thanks!

React Native, node js - update object in different scripts

I'm building an app in React Native,
and I am trying to understand if I need to use useState & useContext to export a user info object,
or I can just get the object from the script, change it, and it will be changed to all the other scripts.
(or if there is a better way to do it so)
Thanks in advance :)
If you update data in your component, always use useState.
Furthermore if you store an array or an object into your state, it's a good practice to update the array/object, and then update your state with a spread operator (this will create a new array/object, and fired your useEffect and UI)
Example :
If you do a simple :
const [stateArray, setStateArray] = useState(["foo"])
stateArray[0] = "new foo"
All the components that consume the stateArray[0] will not update and continue to display a simple foo
This is caused becaused this update doesn't triggered a refresh as you're array isn't update, but one of it's component (not detect by React).
If you want an update, you need to do :
const [stateArray, setStateArray] = useState(["foo"])
stateArray[0] = "new foo"
setStateArray([...stateArray])
This will create a new array, and as such, triggered a new render of your component.
And the same logic applied for object, if you only update one of its value, there will be no update, you need to create a new object :
Example :
const [stateObject, setStateObject] = useState({foo: "foo"})
stateObject.foo = "new foo"
setStateObject({...stateObject})

How to sync two counters in React js using hooks?

I am new to react js,
I want to connect two counters in React js, As if one counter value gets increased by one the other counter value should get decreased by one, And on the button click, I need to add a new set of counter pairs. Can anyone suggest to me a solution? Thank you.
If you want to create a counter pair and have to do it multiple times, I would suggest to use custom Hooks.
I have created one for the purpose named useCounter.
Here you have to pass an array of length 2 if initial state of counter.
And the hook will return [couters, updateCounter, err] the array.
You can refer to this code for insight.
Hook: https://codesandbox.io/s/happy-swartz-ikqdn?file=/src/counterHook.js
Component using hook: https://codesandbox.io/s/happy-swartz-ikqdn?file=/src/pair.js
Note: goto https://ikqdn.csb.app/pair in codesandbox browser

React -> State Management

I am a beginner with React. I want to build an application similar to the page (howmuchtomakeanapp.com). That means that for every choice on a route a user does, a price will be added to the total, but when going back with the back button the price will return to the previous one. I know it is state management but I actually have no clue how to do it even after reading the whole react docs.
The React state is stored locally within a component. When it needs to be shared with other components, it is passed through props. In practice, this means that the component that needs access to a changeable value will keep that value in its state and if it can be changed by subcomponents a callback must be passed to handle the change.
To learn more about components and props, this is the link to the React documentation itself: https://reactjs.org/docs/components-and-props.html.
I recommend you take a look at Redux (https://redux.js.org/), that is a predictable state container for JavaScript apps.
Based on your description I assume you keep your price as a number and add to it the more steps you go further?
I dont think you need to do anything special besides:
My approach would be to keep an array with all the prices, that way you can always remove the last when you click on the prev button. Add one price everytime you select one and navigate to the next route. To display the total you just add the array together:
const prices = [3.5,5,10,5.76,23];
const total = prices.reduce((p, c) => p + c, 0);
Does that help?

ReactJS issue on my test app

So, I've been working through my first ReactJS app. Just a simple form where you type in a movie name and it fetches the data from IMDB and adds them as a module on the page. That's all working fine.
However each movie module also had a remove button which should remove that particular module and trigger a re-render. That's not working great as no matter which button you click it always removes the last movie module added rather than the one you're clicking on.
App:
http://lukeharrison.net/react/
Github codebase:
https://github.com/WebDevLuke/React-Movies
I'm just wondering if anybody can spot the reasoning behind this?
Cheers!
Just a hunch, but you should use a unique key, not just the index of the map function. This way React will understand that the movies are identified not by some iterating index, but an actual value, and that will probably solve your issue.
var movies = this.state.movies.map(function(movie, index){
return (
<Movie key={movie} useKey={index} removeMovieFunction={component.removeMovie} search={movie} toggleError={component.toggleError} />
);
});
This is because React re-evaluates your properties, sees that nothing has changed, and just removes the last <Movie /> from the list. Each Movie's componentDidMount function never runs more than once, and the state of Movie 1, Movie 2 and Movie 3 persists. So even if you supply search={movie} it doesn't do anything, because this.props.search is only used in componentDidMount.
I'm not exactly sure why it isn't rendering correctly as the dataset looks fine.
Looking at the code, I would change your remove function to this...
var index = this.state.movies.indexOf(movieToRemove);
console.log(this.state.movies);
if (index > -1) {
this.state.movies.splice(index, 1);
}
console.log(this.state.movies);
this.setState(this.state.movies);
My assumption is that, the state isn't being updated correctly. Whenever updating state, you should always use setState (unless the convention changed and I wasn't aware).
Also, you shouldn't need to explicitly call forceUpdate. Once setState is called, React will automatically do what it needs to and rerender with the new state.
State should be unidirectional (passed top down) from your top level component (known as a container). In this instance, you have state in your top level component for search strings and then you load individual movie data from within the "Movie" component itself via the IMDB API.
You should refactor your code to handle all state at the top level container and only pass the complete movie data to the dumb "Movie" component. all it should care about is rendering what you pass in it's props and not about getting it's own data.

Resources