问题描述
- 我正在尝试构建一个反应应用程序,我可以看到类似于stackoverflow的通知。
- 当我打开两个不同的选项卡并打开stackoverflow时。我在两个不同的标签中看到了通知。
- 但是当我点击该通知图标时,数字显示。
- 同样在另一个标签中也是数字disaapears而不刷新页面。
- 当我在Chrome浏览器中点击声誉时,我通过打开ie和chrome
- 分析了stackoverflow网站我看到了一个网络呼叫发生在IE浏览器中而不刷新数字。
- 我在本地存储和会话存储中看到了一些值。
- 是可以实现api调用,暂时可以实现使用模拟数据
- 我构建标签ui并重定向到标签页
- 所以我谷歌发现此链接
消息通知方案
demo.js
anotherPage =()=> {
console.log(redictToStepper --->);
this.props.history.push(/ anotherPage);
if(!event){
console.log(window --->);
event = window.event;
} //即suq
if(!event.newValue)return; //如果没有价值可以使用
if(event.key ==getSessionStorage){
console.log(window --->);
//另一个标签要求sessionStorage - >发送它
localStorage.setItem(sessionStorage,JSON.stringify(sessionStorage));
//另一个标签现在应该有它,所以我们已经完成了它。
localStorage.removeItem(sessionStorage); //< - 也可以做短暂超时。
} else if(event.key ==sessionStorage&&!sessionStorage.length){
//另一个标签发送数据< - 得到它
var data = JSON。解析(event.newValue);
for(数据中的var键){
sessionStorage.setItem(key,data [key]);
}
}
//监听localStorage
的更改if(window.addEventListener){
console.log(window ---> ;);
window.addEventListener(storage,xxx,false);
} else {
console.log(window --->);
window.attachEvent(onstorage,xxx);
}
//向其他标签询问会话存储(这只是触发事件)
if(!sessionStorage.length){
localStorage.setItem( getSessionStorage,foobar);
localStorage.removeItem(getSessionStorage,foobar);
}
};
pageOne.js
render(){
const {
showSearchResults,
searchText,
typeAhead,
typeAheadMode,
canEdit,
value
} = this.state;
const {classes} = this.props;
return(
< div className = {classes.root}>
< AppBar position =staticcolor =default>
< ; Tabs
value = {value}
onChange = {this.handleChange}
indicatorColor =primary
textColor =primary
variant =scrollable
scrollButtons =auto
>
< Tab label =Radiobutton One/>
< Tab label =checkbox Two/>
< / Tabs>
< / AppBar>
{value === 0&&< TabContainer> Notification One< / TabContainer>}
{value === 1& ;&< TabContainer>通知二< / TabContainer>}
< / div>
);
}
解决方案我无法确定你的codepen和anotherPage函数试图实现,所以我向你提供。在两个不同的窗口中打开它,查看共享的通知数。
请注意,建议的本地存储解决方案仅在浏览器不共享的同一浏览器上工作他们的本地存储。
这里是如何在两个窗口之间同步本地存储,而不进行任何远程API调用:
首先让添加一个事件监听器。第一个参数是事件类型(这里我们正在监听存储),第二个参数是回调。请注意,收听存储事件仅在两个窗口之间起作用(从窗口更新存储不会触发自己的侦听器):
componentDidMount(){
window.addEventListener(storage,this.handleStorageUpdate);
}
当你不是时,请记得删除此监听器再使用它(可能在componentWillUnmount上)以防止任何臃肿。
componentWillUnmount(){
window.removeEventListener( storage,this.handleStorageUpdate);
}
现在让我们来看看我们的听众。它将接收所有存储更改,但我们只想收听通知更改。当通知在存储中发生变化时,我们希望更新我们的组件状态以使用新值触发重新呈现:
handleStorageUpdate = storageChange => {
if(storageChange.key ===notifications){
this.setState(()=>({notifications:Number(storageChange.newValue)}));
}
};
现在,我们可以让两个窗口监听彼此所做的更改。
让我们给出增加通知金额的方法:
handleIncreaseNotification =()=> {
const notifications = this.state.notifications + 1;
localStorage.setItem(notifications,notification);
this.setState(()=>({notifications}));
};
当增加通知数量时,您将设置要由其他窗口使用的本地存储项目。由于您没有收听自己对本地存储的更改,因此您需要将状态设置为此新通知数。
您希望直接看到通知计数打开窗口时,请记住在组件生命周期的最早状态之一获取本地存储的值:
构造函数(道具){
super(道具);
const notifications = localStorage.getItem(notifications)|| 0;
this.state = {notifications:Number(notifications)};
}
最后你可以渲染整个组件:
render(){
const {notifications} = this.state;
返回(
< div>
< div>我有{notification}通知< / div>
<按钮onClick = {this.handleIncreaseNotification}>增加< / button>
< / div>
);
}
- I am trying to build a react app where I can see notifications similar to stackoverflow.
- when I open two different tabs and open stackoverflow. I see notifications in two different tabs.
- but when I click that notification icon the numbers diappear.
- similarly in another tab also number disaapears without refreshing the page.
- I analysed the stackoverflow site by open in ie and chrome
- when I click reputation in chrome browser I see a network call happening and in IE browser without refreshing the numbers diappear.
- I see some values in local storage and session storage.
- is it possible to achive withot making api calls, for time being can we achieve using mock data
- I build the tab ui and redirect to the tab page
- so I google and found this link browser sessionStorage. share between tabs?
- used it in my react code, for some reason local storage is not setting up
- its going into this method anotherPage
- but storage key value is not adding.
- debugged by putting consoles, but its not printing anything inside window events.
- can you tell me how to fix it show that I can share the session between different links and tabs.
- providing my screenhot code snippet and sandbox below
repuation notifications scenariomessage notifications scenario
https://codesandbox.io/s/material-demo-j5ec5
demo.js
anotherPage = () => { console.log("redictToStepper --->"); this.props.history.push("/anotherPage"); if (!event) { console.log("window --->"); event = window.event; } // ie suq if (!event.newValue) return; // do nothing if no value to work with if (event.key == "getSessionStorage") { console.log("window --->"); // another tab asked for the sessionStorage -> send it localStorage.setItem("sessionStorage", JSON.stringify(sessionStorage)); // the other tab should now have it, so we're done with it. localStorage.removeItem("sessionStorage"); // <- could do short timeout as well. } else if (event.key == "sessionStorage" && !sessionStorage.length) { // another tab sent data <- get it var data = JSON.parse(event.newValue); for (var key in data) { sessionStorage.setItem(key, data[key]); } } //listen for changes to localStorage if (window.addEventListener) { console.log("window --->"); window.addEventListener("storage", "xxx", false); } else { console.log("window --->"); window.attachEvent("onstorage", "xxx"); } // Ask other tabs for session storage (this is ONLY to trigger event) if (!sessionStorage.length) { localStorage.setItem("getSessionStorage", "foobar"); localStorage.removeItem("getSessionStorage", "foobar"); } };
pageOne.js
render() { const { showSearchResults, searchText, typeAhead, typeAheadMode, canEdit, value } = this.state; const { classes } = this.props; return ( <div className={classes.root}> <AppBar position="static" color="default"> <Tabs value={value} onChange={this.handleChange} indicatorColor="primary" textColor="primary" variant="scrollable" scrollButtons="auto" > <Tab label="Radiobutton One" /> <Tab label="checkbox Two" /> </Tabs> </AppBar> {value === 0 && <TabContainer>Notification One</TabContainer>} {value === 1 && <TabContainer>Notification Two</TabContainer>} </div> ); }
解决方案I had trouble figuring what your codepen and the anotherPage function was trying to achieve, so I am providing you this codepen. Open it in two different windows and look at the shared number of notifications.
Please note that the suggested Local Storage solution is working only on the same browser as browsers does not share their Local Storages.
Here how to synchronize your Local Storage between two windows, without making any remote API call:
First let add an Event Listener. The first argument is the event type (here we are listening to storage), the second one is the callback. Note that listening to storage event works only between two windows (updating storage from a window will not trigger its own listener):
componentDidMount() { window.addEventListener("storage", this.handleStorageUpdate); }
Remember to remove this listener when you are not using it anymore (potentially on componentWillUnmount) to prevent any bloat.
componentWillUnmount() { window.removeEventListener("storage", this.handleStorageUpdate); }
Now let's take a look at our listener. It will receive all storage changes, but we only want to listen to the notifications changes. When the notifications changes in the storage, we want to update our component state to trigger a rerender with the new value:
handleStorageUpdate = storageChange => { if (storageChange.key === "notifications") { this.setState(() => ({ notifications: Number(storageChange.newValue) })); } };
So now, we are able to have two windows listening to the changes made by each others.
Let's just give a way to increase the amount of notification:
handleIncreaseNotification = () => { const notifications = this.state.notifications + 1; localStorage.setItem("notifications", notifications); this.setState(() => ({ notifications })); };
When increasing the number of notifications, you are setting the Local Storage item to be consumed by the other window. As you are not listening to your own changes of Local Storage, you need to set your state to this new number of notifications.
As you want to see the notification count directly when opening the window, remember to get the value of your Local Storage at one of the earliest state of your component lifecycle:
constructor(props) { super(props); const notifications = localStorage.getItem("notifications") || 0; this.state = { notifications: Number(notifications) }; }
Finally you can render the entire component:
render() { const { notifications } = this.state; return ( <div> <div> I have {notifications} notifications</div> <button onClick={this.handleIncreaseNotification}>increase</button> </div> ); }
这篇关于反应应用程序本地存储没有设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!