I am new to React and a bit struggling with state in React and how and where we need to use it. So far, I found out that "If modifying a piece of data does not visually change the component, that data shouldn’t go into state". So, state is all about re-rendering the UI(I hope I am correct). So, the question I want to ask is Is it true that we use state only for re-rendering the UI only?, nothing else and nothing more?
You can use state in your class components. State is like private data of your component that may change by action made by user.
State is immutable. This means you can not change state directly in following way this.state.someVal = "smth". The only way to change state is using this.setState() method.
When you change state value React automatically re-renders your component without refreshing the page. In other words React.js reacts to your changes
State is an object that is directly tied to rendering the component. The reason why you can't change State directly with say this.state.foo='bar' is that React would have no way of knowing that it needed to re-render the component if you did that. Thus there is a setState method to change the state, which under the hood calls the render function of your component.
Therefore, if you have some data that has nothing to do with rendering the component, you don't want to put it into state, as setting its value will cause unnecessary renders to occur. If you're using class components, you can just put that data on the class directly: this.foo='bar'.
Basically yes! Two examples might be: A - holding a list of items (shopping list, or todo items) that are rendered directly to the UI, that are subject to change as the user adds and removes items. B - a value that determines whether or not you want something to show up on your UI, for example, you might have a state value called 'showNavbar' that is either true or false, depending on whether you want the user to see a navigation bar.
I hope that helps make sense of it in a basic way :)
We use the state for rendering the UI.
Also, I think the State allows React components to change their output over time in response to user actions, network responses, and anything else, without violating this rule.
For this, We use the 'setState' method.
setState() is the only legitimate way to update state after the initial state setup
Related
Lately I've been working on a React app.
In one of the pages which was suffering from slow load, I discovered there was some updates to state, and those variables where not meant to be shown to end user, and they were there to be checked later when some event was raised.
Since those were arrays, I mutating the state directly and event without "setState"ing it (I know mutating the variable is not recommended at all!).
Later when the Event was raised, state variable had correct data and since redundant "setState"s where removed, the page had a significant speed boost and the problem was solved.
Anyone has any similar experiences with "setState" in react?
What do you think about this?
...I discovered there was some updates to state, and those variables where not meant to be shown to end user...
Then they shouldn't be part of state, they should just be properties on the instance (in a class-based component, which I assume you're using; variables you close over in a functional component). state should only contain things that, when changed, cause a re-render. For that reason, you should only change them via setState, so the render is triggered. You're getting away with breaking the rule because what you're changing isn't related to rendering.
Never mutate the state object (or any objects it refers to) directly. But you can mutate non-state properties (or things you close over), that's fine.
If you need those variables to be stored in actual state but them does not have to trigger a render you probably need to implement shouldComponentUpdate lyfecycle callback:
shouldComponentUpdate(nextProps, nextState) {
return nextState.myPropertyThatTriggersRender != this.state.myPropertyThatTriggersRender;
}
Doing that, if all your state's properties that trigger render are checked, other state properties won't trigger a render. But will be still available in state object.
In order to improve performances, you can implement the same check on the child elements (if they are components) that are going to be rendered.
shouldComponentUpdate(nextProps, nextState) {
return nextProps.myPropThatTriggersRender != this.props.myPropThatTriggersRender;
}
From React's DOC:
Use shouldComponentUpdate() to let React know if a component’s output
is not affected by the current change in state or props. The default
behavior is to re-render on every state change, and in the vast
majority of cases you should rely on the default behavior.
I'm using ember.js(version 3.7) and I bite confused now. Now, I'm working on optimizing the code part for our app. First I'll try to find What are the things are re-render in components? After getting into this topic I bite confused with it.
In ember they used didRender() method to trigger re-rendering things (jQuery DOM Manipulation, Asnyc function loading,etc...). Right now I don't have much idea about re-render in ember. Can someone explain to me re-render in detail? And, please share if you have any resource about re-render in ember.
Thanks in advance.
didRender hook doesn't about triggering a re-render. It is described as the Guide that you shared the link of:
You can leverage this hook to perform post-processing on the DOM of a component after it's been updated.
You might want to do something about sizes or focuses or scrolls. To achieve that you need to wait till your rendering finishes. Because otherwise you cannot get the exact values and positions of the components. For those cases you can use didRender hook.
For example:
- if you want to focus some parts of the view
- if you want to scroll some parts of the view
- if you want to resize some components
- if you want to call a third-party libraries which tries to access DOM element.
etc. You can use this hook.
For sure, if you do something that affects to component's values, it can trigger a re-render. But this is something that you normally shouldn't do.
Let's have one more clarification of re-render:
As components are rendered, re-rendered and finally removed, Ember provides lifecycle hooks that allow you to run code at specific times in a component's life.
(Ref)
Guide says about 3 main phases (Ref):
Initial Render
Re-render
Component Destroy
In here Re-render means, if an argument or a property of a component changes, it starts to re-render itself. For example, think of a person-card component which displays the properties of a person. Such as {{person-card person=model.person}}. Whenever the person parameter changes, the component will re-render.
I have been using redux .. i am changing state tree using using redux actions ...
sometimes updating the state does not refresh the component .. i have to force update by this.forceUpdate() .. why is this happening? Under what condition does this happen.. usually updating state tree using an action automatically refreshes the component but sometimes it does not.. another question is that what if the state change needs to re-render a different component ?? how to i force update other components from another component ??
Are you sure what your return new object from your reducers?
If your return the same object (only mutated) redux does not understand what data has changed.
If you need rerender component when data change that that component should be dependent on these data. forceUpdate is a really bad practice.
Sometimes it's not obvious: where I should keep state of React view, i.e. active tab, selected option, toggler value, is input validated flag?
Actually there are two options:
Throw an action and keep that data in store
Keep that data as view's state
Which of them is better? Are stores intended only for data from server?
My considerations:
That's bad to keep that data in store, because that lead to chain of actions. Example: you need to download data on tab selection - so you trigger an action NEW_TAB_SELECTED and from the store which handle it trigger a new action DOWLOAD_TAB_DATA.
Keeping data in view allow to avoid the first action (NEW_TAB_SELECTED) and avoid action chains. But how to keep selected tab if I want to leave this view?
Things that should be kept in the component's state are things which only affect that component.
So, for example, if you have a component which opens to reveal more content then the isOpen flag can be kept in state because it's internal to the component.
If the information is not part of the component (such as the text of a message and whether the message has been read) then it should be kept in a store and circulated through the app as needed.
Changing the state of a component will cause it to redraw, so try to keep state to the minimal possible representation of its state, and only store those properties in this.state.
Therefore, from what I can gather from your question, I'd suggest keeping active tab, selected option, toggler value and whether the input is validated in this.state. They are all properties of the component but don't affect any other components. I'd keep the data which populates the views in a store. I'd keep the flags which indicate the state of the view in this.state.
Hope that helps.
Scenario: I have an react app which has its state in flux store (async load), passing data down to Root component which is passing data to its children and so on.
now: text input field, nested somewhere deep down in node tree, has its initial value done in getInitialState from a prop (the prop has been passed down), and on onChange event its state is set to typed value. So far book example.
Now let's 'submit' the form, action is triggered, ajax call has been made, data came back changed, passed to the store which emits event to Root component, the node tree gets re-rendered again, BUT of course getInitialState is not triggered again, and the field still has the last typed in value.
I don't think I want to initiate the whole action-store-root-children-reRender loop on every single key stroke, right?
Question: How do I get the input's state to be fresh from the passed prop (the store one)
THOUGHT: Hmm, I can actually tell when I'm initiating re-render from the ROOT, by setting a store 'flag' in ROOT's componentWillUpdate() then setting it back in componentDidUpdate() - then all the child components can know if it is ROOT intent to re-render or just a parent non-store initiated change.
Keep the form's values in the store instead, and don't using any local component state at all. When the form is edited trigger actions to update the store and re-render the app.
First of all what you are doing is an antipattern. State should not be set equal to props. Your props should not be state.
The React docs are pretty clear on updating props.
Check out this link: https://facebook.github.io/react/docs/component-specs.html
componentWillReceiveProps(object nextProps)
You should think about implementing this lifecyclemethod it will help you to be aware of prop changes.
But please think about seperating props and state - there is a reason why React Framework has both. But that is a different topic.
EDIT1:
If you want to update your stores state then call a flux action that referes to the corresponding store and pass in the props as payload inside of the lifecyclemethod above.
Hope this helped.