I would like to know what is the best way to refresh the page after typing.
For example, I press a button that modifies the name of a product, how can I do that from the moment I validate my modification, the changes appear immediately, without having to manually refresh the browser page.
I saw some example with react-router, doing a redirect or using 'history.push', I also saw with the 'window.location.reload (false)' but it doesn't feel right because you can 'see' that the page refresh (yes you don't manually refresh but ... maybe there is something better to do)
Well, the best way is to not refresh the page at all.
Specially if you are using React. Every piece of data that you display on your UI is supposed to be stored in some kind of state. Even if that data should somehow be validated asynchronously (I think this is your case), once done, you should trigger a state change that will cause the interested components to re-render and display the new information.
You can use useState hooks of react to view the changes without refreshing the window.
In every state change, which means the change of value on the given state, react automagically rerender to show the latest data.
const [productName, setProductName] = useState('');
cosnt handleButtonClick = (name) => setProductName(name)
return (
<>
Production Name: {productName} // Product name changes on every button click.
<button onClick={() => handlebuttonClick(dynamicallySendRequiredDataFromHere)}> Change product name </button>
<>
)
It all depends on your requirement actually.
If you want to reload the page to get something which can only be achieved by reloading then use
window.location.reload()
If you want to reload just to get the data then make the API call and connect your component with the state that gets the value after the API call
If you want to maintain the history stack the use
history.push()
If you dont want to maintain the history stack the use
history.replace()
Some fancy times when you want to set cookie or storage to your page but dont want to refresh current page you can use window.open with the origin and target
window.open(window.location.origin, '_blank')
Related
I'm working on a react project where I created a component using <Promp/> from react-router to implement a confirm dialog that shows up when user attempts to leave the route without saving current changes:
The component works properly when I try to leave the current route, but I also want to display the dialog when user clicks a button meant to discard the changes intentionally. Since modal only displays based on a route change, a workaround that I could think of is to call history.push when button clicked:
const history = useHistory();
const { pathname } = useLocation();
const onCancel = () => {
history.push(pathname);
};
that it pushes the same route and this way changes are discarded and user stays on the same page as if nothing happens, but now the problem with this workaround is that user won't be able to go back to previous route because history stack is getting filled with the same location, so in order to solve this I tried to use history.replace which is meant to replace the top of the stack instead of pushing a new element, but it's not working this way and is acting like history.push adding new elements with the same location.
Is this bug or am I missing something? what could be a workaround for this?
Any suggestion is welcome.
Seems to me that you want to reload, i.e. re-render, the page. For that, you can use history.go(0).
Take a look at this: How do I reload a page with react-router?
I try to use the window.history.replaceState method just to show the URL shown in the browser.
window.history.replaceState("","","newurl.php");
Well, this works well and changes the URL. But what is this "State" that I set to "" here? And how should I change my code if I simply want to be the State as before? (As I said... I just wanted to change the URL and this works well, not to change the state...)
.replaceState() a way to associate some data (any data that can be structured cloned) with the current location - without reloading the page. There's also pushState, that does the same thing, but you can also use the browser's back button to go back to the previous displayed url / state.
If you don't use these for something else, you don't have to care about the state you set (it's only visible to your website).
If you, on the other hand, do use states, and don't want to change it, you can set the same state as it was before. You can get the current state with history.state:
window.history.replaceState(window.history.state,"","newurl.php");
I'm developing with react-router-dom. Now, I'm creating a page where users can enter information in a form. What I want to do is prevent the user from losing the information they enter if they accidentally return to the previous page.
I first found a way to stop the browser back in the article below. It seems that the moment you return to the previous page, you immediately return to the original page, effectively preventing you from returning to the previous page.
React.useEffect (() => {
return () => {
props.history.goForward ();
}
}, []);
React Router Dom v4 handle browser back button
However, in this case, the previous page will be returned once, so all the current page information (state) will be reset. Is there a solution to prevent the state from resetting?
Or is there a smarter way to solve this?
Below, I have prepared an image for explanation.
You have several ways to approach your answer, but all of them have 1 concept, and that is Higher-order-component, so in this case, you have to have a top-level component (Higher than react-router), so when the location has changed, you don't lose the information in the state. in another word, you have to have a general state.
So how you can reach this goal? you have several ways and I'm here to help you use them.
redux - https://redux.js.org/.
context - https://reactjs.org/docs/context.html.
react state - https://reactjs.org/docs/higher-order-components.html.
localStorage or sessionStorage - https://www.robinwieruch.de/local-storage-react.
...
these are just some examples of what you can do to prevent losing state when the browser location has changed.
I'm doing a Chrome plugin for Facebook and I want to modify a post using external javascript. I can change the textContent of a span but the state is not changed and the Save button is not activated.
The html looks like that :
<div class="" data-block="true" data-editor="1477r" data-offset-key="a699d-0-0">
<div data-offset-key="a699d-0-0" class="_1mf _1mj">
<span data-offset-key="a699d-0-0">
<span data-text="true">test</span>
</span>
</div>
</div>
The component in React Developper Tools :
[
I profiled a change of the text and this is the result for a 6 ms timeline activating the save button.
There are ways to modify a React input but did not found ways for my problem :
https://github.com/facebook/react/issues/11488
https://github.com/facebook/react/issues/10135#issuecomment-314441175
How can you change a Facebook post and his state with external javascript?
What would you do?
That’s not possible, you can’t imperatively mutate a React element tree from outside the app. You’d have to declaratively render a tree, either by modifying Facebook’s frontend code (beware of legal ramifications) or implementing your own post UI.
While it's nearly impossible to change the state of React component from your plugin, nothing stops you from emulating user's input by sending keystrokes, mouse clicks etc. The only thing you need it to figure out - which DOM-element listens to these events (not necessary one of those 4 in you question).
About the possibility of direct state change: let's say the component you need to changes is a functional one. Then it has a form of
Component() {
const [state, setState] = useState(...)
...
setState(something)
...
}
so you need to somehow access the setState function of the component. But how? It's private to the function call. If you think that instead you can call the useState directly, then be aware that in another component it will return another setState. I have no idea what would happen if you'll call useState outside of a component, but surely it will not be able to guess which setState you want.
If you want you can check the source code of react-devtools to find out how you can dig out the state from the depths of React... but would you really want to try? And for what? The next time Facebook or React will be updated your code will definitely break.
i am trying to show the user a payment popup as soon as he clicks on a payed object.
But after he pays he should directly enter the content he clicked on.
Therefore i think its a good solution to solve this with the router, because i want every link on the page that redirects to this content to show this popup.
My problem is i want to show the popup before redirecting the user.
So i tryed the onBeforeAction hook and stuff but everything working with the iron router seems to only hook in after the URL of the browser changed and the current template was unloaded.
Do you have an idea how to get this kind of behavior?
Cheers
Based on this answer, here is how you can hook the router using Router.onStop():
// onStop hook is executed whenever we LEAVE a route
Router.onStop(function(){
//check if the current route is the page from where you need to show your
//popup and show it based on, for instance, a session variable containing
//the previously clicked content id.
});
It's a common use case that I don't think is directly achievable within the iron router framework at present (although I would be delighted to be corrected!). As you've discovered, onBeforeAction is run before the page has rendered but after the new route has been run, so the old page has already disappeared.
Effectively, you're looking to queue the running of a new route until a certain action has been completed. The use case for which I've experienced this requirement is page transitions, for which the best solution appears to be to do completely the opposite of what you propose: i.e. to add the logic to an event attached to the link, and only redirect to the new route once that logic has been satisfactorily completed (i.e. the popup has been closed in your case).
I agree that doing something in the router would be a sensible way to approach this, but I'm not sure it's possible in iron router as things stand. Note that this has already been raised though!
Will this workshop?
'unload - runs just once when you leave the route for a new route.'
From
https://github.com/EventedMind/iron-router/blob/devel/DOCS.md#unload-hook