I have 2 separate components that are very "far" from each other (no parent-child relationship to pass props around):
A component that does a count-down and navigates away when timer is hit.
A text field down below the page.
I want to stop the timer when the user is editing the text field.
Besides saving an "isEditing" state into Redux or window (or some state management) from component #2, and monitoring that state from component #1, are there any standard React way to achieve this?
Perhaps there is a way for a ref to listen to another ref's property change, such as focus?
Related
I am trying to set the focus on my React page but it doesn't work because the component updates which I think overrides the componentDidUpdate.
is there another way to do this?
this is the code I normally use to focus
document.querySelector("#input-box").focus();
If you are using react you should ideally be using refs and using them to set focus. Check the accepted answer for Set focus on input after render
If you have a problem of the component losing focus a lot, this can happen if the key value that you set for the component is not unique. React uses the key value that you set to track components across render cycles. If the key is generated incorrectly then you can have a scenario where the component loses focus across render cycles. For e.g., a controlled input box when a user is typing in it.
For a project, we want to have notifications visible throughout all views in the app.
The sidebar menu allows users to move between views, and is on the same level as the notification component and the websocket component react-stomp. The router is used to change the view on the next level depending on the selected menu item.
Our problem is that if a new message arrives, we need to pass it down to the view as props, and of course this triggers a re-render of the entire component.
Is there a way to avoid this rerender?
We would like to avoid redux, though we are aware it is a possible solution.
By default, if props changes react will trigger re-render. If you want to avoid rendering a componenet you can use the hook shouldComponentUpdate(nextProps, nextState)
Quoting React's documentation:
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.
For further reading visit their docs
Have you tried experimenting with react lifecycle event hooks ?
You could use REACT CONTEXT API if you want to avoid using a state manager like Redux or MobX
I have a React app that takes the user through various steps. I want to have the ability to use the browser's "back" button to go back to a previous step. Now I'm thinking of using react-router to do this.
Currently, I am simply reacting to events and calling setState on my top-level component.
My question: Does all state have to be reflected in the URL, or saved into local storage? Or can I keep the component's state and just have react-router change some props on the top-level component? When I do that, do I risk loosing the component's state (e.g. because React doesn't identify the old and the new components)?
I want to have simple URLs like /step1, /step2... . These do not reflect everything that is going on in the app. Specifically, I don't need or want the ability to directly enter such an URL. There are also privacy concerns. I am happy with having the application's state in the main component's ephemeral state. In other words, my application's state is not a pure function of the route.
I want to mainly use react-router to make the back button act as a glorified undo / go to last step button, and only secondly to navigate to other components. Any idea or small snippet showing how to do that? Or is react-router not suited for this?
When React navigates from one component hierarchy to another (such as react-router links / history navigation) it only unmounts the components that do not exist in the new component hierarchy. State is only lost in unmounted components. If your state is properly stored at the top level which only goes through rerendering and not remounting, you should retain it.
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.