如何聆听本地存储的价值变化做出反应?

时间:2019-06-19 04:40:18

标签: reactjs events local-storage addeventlistener

我想在用户登录时显示一个按钮。如果用户未登录,那么我不显示按钮。用户登录时,我将设置本地存储值。当我在登录组件中设置本地存储时,Header组件必须侦听该事件并显示按钮。我正在使用addEventListener进行监听。但它没有监听。

我不知道在标题Component中侦听的位置。

// HeaderComponent(header.js):

class HeaderComponent extends Component {
    componentDidMount(){
        if(typeof window!='undefined'){
            console.log(localStorage.getItem("token"));
            window.addEventListener("storage",function(e){
               this.setState({ auth: true});
            })
        }
    } 
    render() {

    return (
        <div className="header">
            <div className="container">
                <div className="header-content">
                    <img src={logo} alt="logo"></img>
                    <div className="nav-links" >
                        <ul >
                            <li>Home</li>
                            <li>About</li>
                            <li>Services</li>
                            <li><NavLink activeClassName="active" to="/upload" >Upload</NavLink></li>
                            <li><NavLink activeClassName="active" to="/signup"> Sign Up</NavLink></li>


                           { this.state.auth? <li onClick={this.onLogout}>Logout</li> :null}

                        </ul>
                    </div>
                </div>
            </div>

        </div>
    );
   }  
}

// loginComponent(login.js)

class LoginComponent extends Component {
    constructor(props) {
        super(props);
        this.onSubmit = this.onSubmit.bind(this);
    }
    onSubmit(event) {
        const data = {
            username: document.getElementById('name').value,
            password: document.getElementById('password').value
        }
        axios.post(`http://localhost:4000/user/login`, data).then(res => {
            this.props.history.push("/");
            localStorage.setItem("token",res.data.token);
            localStorage.setItem("auth",true);
        }).catch(err => console.log(err));
    }


    render() {
        return (
            <section class="log-in">
                <div class="card-col">
                    <form>
                        <h3>LOG IN</h3>
                        <div class="form-controls">
                            <input id="name" type="text" placeholder="username" class="input"></input>
                        </div>
                        <div class="form-controls">
                            <input id="password" type="password" placeholder="password" class="input"></input>
                        </div>
                        <button type="submit" onClick={this.onSubmit} class="button" >Log in</button>
                    </form>
                </div>

           </section>

        )
    }

}

1 个答案:

答案 0 :(得分:0)

请注意两件事

  1. storage事件仅在在两个浏览器选项卡中打开同一应用程序时才起作用(用于在同一应用程序的不同选项卡之间交换信息)。存储事件will not fire when both components shown on the same page

  2. 添加事件列表器时,您传递的是function(),而不是数组函数。 function()不会捕获this,因此您应明确bind(this)或将其更改为箭头功能。

    例如

    window.addEventListener("storage",(function(e){
           this.setState({ auth: true});
        }).bind(this));
    

    或者使用箭头功能

    window.addEventListener("storage",(e) => {
           this.setState({ auth: true});
        });
    

简单example

请确保在两个标签(相同的链接)中将其打开。将值存储在一个选项卡中,然后在另一个选项卡中查看该值。