How to reset state of a child reactjs component - reactjs

I have a react.js app which loads data from an API displays a bunch of questions (textboxes, radiolist, checkboxes, etc). The user fills them in and submits all answers back to the API, which then send a new set of questions.
All these questions are in a single object, so I've created parent react.js component which holds the current set of questions in state. When the state changes it re-renders each question below. This works pretty much fine.
The problem is that sometimes the API displays the exact same question for twice in a row, but as this is held in state and react.js is clever enough to know it doesn't need to render a completely new component, because the old one will do (with a few small updates).
The problem is that if I select a radio button on the first one, based on the initial data stored in state of the child component, which was initially set within componentDidMount). But when the second question comes along, because its essentially the same component, the state remains. The constructor is not called again.
I think I should be using one of the other events, perhaps:
componentWillReceiveProps
componentWillMount
componentWillUpdate
but I can't figure out which one is the most consistent one.
I basically want to reset the selectedAnswer everytime the parent has received new data from the API and essentially re-render all child components (but react won't do that).
Edit
I wonder instead of trying to reset this via the internal lifecycle events, whether I can pass in a different set of props into the component, so it can decide whether to re-create or re-render in the usual way.

okay so to optimally do this lets suppose you api which returns the set of questions, it might contain some id associated with it. Using that id create a uniq key for every child component while rendering something like below
<Child key={`${data_id}_${index}`} />
This will ensure that for the same set they do not keep mounting again and again and will only mount if a new data set is fetched in which case data_id will change which would cause remounting of each and every child component

I'd encourage you to check out Redux. It makes managing state much easier. I'd contribute some code on here but I am not sure I actually understand the question. If you linked us to your Github, then I could probably answer this specific question.
Also, it seems like you don't really need to touch state. It sounds more life attaching an event and controlling state that way. For example, using onSubmit, you can make an API call (and whatever else) and then have another function to reset the form state afterwards. It would be pretty straight forward, especially if you are using then/catch Promises.

Related

React: Update a self-contained grandchild from a click even from grandparent

I currently have the following situation:
<GrandParent> // click happens here
<Parent>
<Child> // self-contained with its own state
Is there a way to update the react state inside of the child with a click in the GrandParent? I hate having all this Child-specific code in GrandParent.
Right now, the only way I know to make the code functional is to pull all state into GrandParent and make state changes when the click happens, then pass that state into the child (vis useContext hook).
Update:
So I researched this further and yes, I could use solutions like redux, however this feels overkill for a small app. I did find some non-library solutions that might be a good fit for anyone looking at this question in the future.
The following solution uses 'this' binding. It works even if it's a bit janky. But the downside is that you have a global name space pollution and The grandparent has to have access to the grandchild, which I don't (it's on a different 'page').
https://www.codeproject.com/Tips/1215984/Update-State-of-a-Component-from-Another-in-React
This approach uses an event emitter to signal when a state change should happen. It's pretty clean but uses a library, albeit a tiny one. I like this approach, however, it doesn't feel very 'reacty'.
https://medium.com/#krzakmarek88/eventemitter-instead-of-lifting-state-up-f5f105054a5
Finally, I ended up using this solution. The gist is that instead of using a react context for storing state, you use the context to store functions that trigger state changes. Since the callbacks don't change themselves, you avoid unnecessary redraws and the solution stays within the bounds of normal react.
https://javascript.plainenglish.io/dispatch-an-action-to-update-a-sibling-within-react-e98f5b5041f3
You could use a top-level state management tool like React Redux: https://react-redux.js.org/introduction/getting-started

React Redux, component internal state sync

This is a bit complicated so I'll try to put it as simple as possible.
I have a pretty much complicated reusable component in my app.
Basically, it is a large table with many editing options.
Since this component should be reusable, my thought was that it should manage it's own state.
It also makes sense because this component's business logic is pretty much complicated, and by using redux, I'll probably have to repeat some crazy boilerplates.
On the other hand, this component should be able to have some default data loaded to, and finally, this component is in some cases a part of a form, so I sohuld be able to extract it's data and send it to the server.
Redux can really help with the last two tasks - if I had an easy way to store all component changes in the store, I could easily load the default data from there (because my component will be fully controlled), and it will also be easy to extract data from the store when sending to server.
Although, it has a lot of boilerplate, and I'm not feelinng comforotable to write a componenet specific logic in my reducers, since ideally, they could manage themselves.
Any more ideas about that?
I had one idea that seems to be working, though I am not sure how good it is:
Have a "dataKey" prop to handle default data prop changes, and derive the state from the data
Use some submit callback to extract the data and send to server
Any more thoughts will be very helpful, thakns!
It's hard to provide an extract answer as your question is kind of abstract. But since you are just looking for ideas, this is just an idea which you can try to incorporate with the actual use case.
In this kind of scenario, I would first distinguish my actual data and UI state. Then I will write my component as a controlled component of actual data with the usual value and onChange props. The UI state will be kept in the internal state of the component and it will either be derived from the initial props or initialized with a default value. When the user interacts with the component, if the change affects only the internal state, we can just use setState to update the state. If it affects data also, we can fire onChange prop also accordingly. This way we can keep the actual data in the redux store, but still, keep component specific logic in the component.
As an example, let's say we want to make a text label component with in-line/in-place editing support. I would still keep the props of this component similar to the default HTML input element as value and onChange. But the flag that indicates whether to render a text or input element with 'Submit' and 'Cancel' buttons will be kept in the component as isEditMode. Initially, we can always keep isEditMode as false. But when the user clicks on the text, we change it to true, so that component will render elements for editing and hide the label. While the user changes the text we can keep that intermediate value also in UI state. But when the user clicks the 'Submit', we can fire onChange with the new value in state and change isEditMode also to false. Likewise, we can keep the component as a control component but still use the component state to manage intermediate UI states.
Hope this helps!

Where do I put CRUD operations in a reactjs app?

The web is full of people telling me I'm doing react wrong. I'm sure they're right, since I've just started. A commonly referenced truism is that react is just the view layer. That's wonderful, but it leaves me wondering simply where do I put my other stuff?
I have a pretty straight-forward set of components which together show a list of nested data types and allow some editing, creation, and removal of the things. The components which consume the data have it passed in through props down the hierarchy from a parent that fetches the data. Should those read operations go somewhere else if it's "just the view layer"
What's the best practice for this, the idiomatic way, the react way? Should my delete operation be included with my delete button component? next to the read operation? somewhere else?
I suggest you to try some flux architecture. In this case it will looks similar to described below:
You call action on delete button click, for example actions.deleteUser(1)
Action calls appropriate API
Store connected to your component changes and component state changes
component re-rendered automatically
It depends on Flux that you prefer. The flow may be slightly different. I prefer reflux one
In react, data flows only from parent component to child component. I assume that your state is stored in the parent component, since you have create, update and delete in separate components. The state can only be changed by calling the setState() function on it. Therefore child components cannot modify the state of the application. This can be done only by having a callback function.
The delete function will be written in the parent component and will be passed to delete component as a prop. The delete component will then call the delete function (callback) which will call the setState() upon the state of the parent component and thereby altering the state. Never alter the state of the application without setState().
Hope this helps

React state vs. Redux state (real usecase)

I have read multiple tutorials how to make CRUD in React with Redux bot none of the authors explained why they are using Redux. (Like they are only using it for fancyness or because all other are using it.)
Citate from here:
People often choose Redux before they need it.
Through further researching i learned that Redux is good for:
Share state between components
Let some data be accessable in the entire application
It does not exist a wrong or right. But only the do what makes sense.
My usecase
I have a component that uses a shared component:
¦-- domains/FooManagement/Components/Editor.jsx <-- Most-parent of the editor
¦-- domains/FooManagement/Components/..the children of Editor.jsx
¦-- shared/Components/Tabs/Tabs.jsx <-- Most-parent of the tabs
¦-- shared/Components/Tabs/..the children of Tabs.jsx
Tabs.jsx is used in Editor.jsx.
Which is the right approach?
Approach 1: React state (I think its the right one)
Every dynamic rendering that can happen is stored in the state of Editor.jsx.
onClick on a tab (nested shared component) calls a callback written in Editor.jsx that updates the state in Editor.jsx. This state change then rerenders the new active tab
That means that on every other component like Editor.jsx that uses the same nested Tabs.jsx, the changes for the tabs must be handled in the editor.
Code example:
/**
* domains/FooManagement/Components/Editor.jsx
* or
* domains/BarManagement/Components/Editor.jsx
*/
onTabChange(activeTab) {
this.state.activeTab = activeTab;
this.setState(this.state);
}
I think this is the right approach because:
I dont need the state of the editor or the tabs component in the entire application. But only on this view one time. Like the short term duration definition.
Approach 2: Redux state
Editor.jsx has its own state
Tabs.jsx has its own state
States are stored in Redux
Editor.jsx dont passes data down to Tabs.jsx because Tabs.jsx takes the data from the Redux store
Benefit:
The code example above must not be in Editor.jsx because its not the editor's interests how the tabs component behaves. (Or should the editor interests?)
I think this is bad because
Its too much magic in here. Immagine there comes more components in the editor like sortables, tables, etc. In the Editor.jsx you will not see what can render your view. It is hidden in the other components.
But if its all handled in Editor.jsx, you have the overview and the control of all what must be rendered on any change.
What is the right approach for you?
speaking of real usecases, I'm working on an everyday growing project, at first, pure React state management seemed like a very convenient way to develop, and it was working just fine when the components structures were still somehow flattened, but as we go along it, the project gets more complicated and by complicated I mean, more component become nested, and one parent has a serie of nested children, so we have to pass props all the way from the parent to the most furthest child, and whenever we need to rerender the parent, all the children have to go through this cycle also, as for your case, if you know that your project won't get way more complicated, and Tabs.jsx won't have maybe something like form that contains further nested subForm that contains a Grid maybe, you surely don't need to complicate your life with Redux, but as I stated earlier, for us we started to notice that at this stage, integrating Redux would be considerable

Editing a form is not working on react redux

I am new on react. I am working on react application with redux. I have a form (I am using redux-form) by which I can save data or edit data.
my problem is , In edit mode I populate data using componentWillReceiveProps. and populated perfectly, now when I try to clear any field on form its again fill.
componentWillReceiveProps(nextProps){
this.props.dispatch(initialize('NewProject', nextProps.project.project[0]));
}
I would be grateful for any help.
Is there a reason you're not dispatching this action somewhere else, like in componentDidMount? I can't say without seeing more code, but it's possible that whenever you edit your form, React again calls componentWillReceiveProps and overwrites whatever you did with the behavior you've given your component.
Per the React documentation:
Note that React may call this method even if the props have not changed, so make sure to compare the current and next values if you only want to handle changes. This may occur when the parent component causes your component to re-render.
It may be a good idea for you to move your dispatch to a more predictable event if possible, like componentDidMount. Typically, your render method should be capable of handling different cases if a component has multiple possible states. You could also create an edit and save version of your component, and render one or the other based on the props you receive. The best way to "populate" data, as you put it, is to define propTypes for your component, and then use your props to insert that data into elements in the render method.

Resources