I'm trying to use react-navigation make a reusable SplitView component for React Native where the parent navigators are able to perform navigations on their children. To accomplish this I am using ref's to programmatically perform navigations on nested navigators. However, I am running into an issue where when my app re-renders, all my navigation refs become:
{ current: null }
And I am not able to perform any further navigations.
Here is a link to a Snack project demonstrating this issue. Note that you will have to uncomment lines 13-17 in App.js to see the issue. The commented-out useEffect is there to force an initial re-render. Without it the navigation works just fine.
The docs for "Navigating without the navigation prop" have some notes around initialization issues with this use case but I didn't have any luck with their suggested solutions. I think the issue they are referring to is a race condition before the Navigation container has a chance to mount--I don't think this is what is happening to me because it seems like once my app re-renders I NEVER get access to the correct ref.
It turns out the issue was because I was using createRef instead of useRef. When working with refs + functional components it's necessary to use the useRef hook since createRef will return a new ref on every render, and it's not possible to store the created ref as an instance variable as you would in a class component.
Related
Let's say I've triggered an update of a single React component & as we know by default it will trigger the update of all it's children components.
BUT
How does it work in combination with browser's reflow/repaint ?
How does the whole process look like (step by step) after we trigger a single React-component's update?
By default, the child components would be updated as well, however, that only happens in the virtualDOM, and not the actual DOM.
Changes are made to the virtualDOM, React then checks to see which DOM elements/components are changed/updated, and only those are updated in the actual DOM, it's part of the reason why your React app is fast.
You can refer to this thread for more information, though I think they are more so on class component, not functional component.
When using history.listen, I found it was fired AFTER componentDidMount of my children's component. After Google it, I found this issue.
By following the suggestion of the contributor, the history.listen fired indeed BEFORE the componenDidMount of my children component. But at the same time, I found the history.listen just does NOT fire anymore when navigating between my children's components. This behavior is not mentioned by the lib contributor and is not what I expected to happen.
Reproduce Link: https://codesandbox.io/s/unruffled-rain-q453q?file=/src/index.js
I think I must doing something wrong and because the contributor said it is expected because of the React mechanism.
So here I want to know what's the specific React mechanism is about for routing and know the right way to fulfill my requirement.
Just to be clear, my requirement is when the parent component registers a history.listen:
it should Fire whenever the URL changes, no matter what sync or async.
it should fire AFTER the componentDidMount of its children component.
Could anyone help me, please?
Register in the constructor in the App Component is too late, should create a wrapper that wraps the App component, register the callback first and then pass history to the App component.
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.
Is there a way to stop react from removing/changing nodes embedded in a react component.
For example, I have a react component that acts as a container for a non-react component that manages its DOM on its own. Is there a way to mark such components for reactjs, so that it does not modify its DOM?
In my case, I want my react component to be inline-editable by CKeditor, but react always removes/destroys the editor and all the nodes it has added to the DOM, because they were not defined in the react component itself and so it thinks that those elements should not be there.
Any ideas?
If you return false from a shouldComponentUpdate method on your component, then React will step out of the way and the entire reconciliation process will be skipped for that subtree. Of course, this means that you need to manage all DOM mutations yourself in that area and can't take advantage of React.
Take a look at dangerouslySetInnerHTML on https://facebook.github.io/react/tips/dangerously-set-inner-html.html.
This is the method for adding markup that doesn't sticks to React's update methods and also unsupported tags.
This way you can still update your component, while not updating parts of it.