【问题标题】:React did not update while data change数据更改时 React 没有更新
【发布时间】:2020-09-06 17:41:29
【问题描述】:

我将更新标题组件,其中标题组件有一个名为 App 的父组件。如果用户已连接,我将更新接收 props 的 header 组件中的 HTML,但我需要重新加载以对 header 组件进行更改,我不知道我是否遗漏了什么......

Header.js

import React from 'react'
import {Link} from 'react-router-dom';

export default class Header extends React.Component {
    constructor(props) {
        super(props);
        if (this.props.isAdmin){
            this.setState({isAdmin: true})
        }
        if (this.props.isLog){
            this.setState({isLog: true})
        }
    }



    render() {
        return (
            <nav className="navbar navbar-expand-lg navbar-light bg-light">
                <a className="navbar-brand" href="#">Shop</a>
                <button className="navbar-toggler" type="button" data-toggle="collapse"
                        data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span className="navbar-toggler-icon" />
                </button>

                <div className="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul className="navbar-nav mr-auto">
                        <li className="nav-item">
                            <Link to="/" className="nav-link">Home</Link>
                        </li>
                        <li className="nav-item">
                            {this.props.isLog ? <Link to="/profile" className="nav-link">Profile</Link> : <Link to="/login" className="nav-link">Login</Link>}
                        </li>
                        <li className="nav-item">
                            {this.props.isLog ? <Link className="nav-link" to="/logout">Logout</Link> : null}
                            {!this.props.isLog ? <Link className="nav-link" to="/register">Register</Link> : null}
                        </li>
                        <li className="nav-item">
                            {this.props.isAdmin ? <Link className="nav-link" to="/logout">Administration</Link> : null}
                        </li>
                    </ul>
                </div>
            </nav>
        )
    }
}

Login.js 这里我使用重定向组件到主页,这里不会更新任何数据。如果用户已连接或注销,我必须重新加载页面才能进行更改。

import axios from 'axios';
import React from "react";
import swal from 'sweetalert';
import { loadProgressBar } from 'axios-progress-bar'
import {Redirect} from "react-router-dom";
import 'axios-progress-bar/dist/nprogress.css'



export default class Login extends React.Component {
    state = {
        email: '',
        password: '',
        redirect: false,
    }

    handleChange = (e) => {
        this.setState({
            [e.target.name]: e.target.value,
        })
    }

    handlePost = () => {
        loadProgressBar()
        if (localStorage.getItem('token')){
            return (
                swal({
                    title: "Already Connected !",
                    text: "You are already connected !",
                    icon: "error",
                    button: "Ok",
                })
            )
        }
        axios.post(axios.defaults.baseURL + 'login',{email:this.state.email,password:this.state.password})
            .then(res => {
                localStorage.setItem('token',res.data.access_token)
                this.setState({redirect:true})
            })
            .catch(err => {
                swal({
                    title: "Bad credentials !",
                    text: "Verify email and password !",
                    icon: "error",
                    button: "Ok",
                });
            })
    }

    render() {
        if (this.state.redirect){
            return <Redirect to='/' from='login' message="Your are connected"/>
        }
        return (
            <div className='container'>
                <div className="form-group">
                    <label htmlFor="email" className="text-dark">
                        Email
                    </label>
                    <input type="text"
                           name="email"
                           id="email"
                           onChange={this.handleChange}
                           placeholder="Entrer votre mail"
                           className="form-control"/>
                </div>
                <div className="form-group">
                    <label htmlFor="password" className="text-dark">
                        Mot de passe
                    </label>
                    <input type="password"
                           name="password"
                           id="password"
                           onChange={this.handleChange}
                           placeholder="Entrer votre mot de passe"
                           className="form-control"/>
                </div>
                <button type="submit" className="btn btn-info" disabled={!this.state.email || !this.state.password} onClick={this.handlePost}>Se connecter</button>
            </div>
        )
    }
}

App.js

import React from 'react';
import {BrowserRouter as Router, Switch, Route, Redirect, Link} from 'react-router-dom';
import Login from "./pages/Login";
import Home from "./pages/Home";
import Profile from "./pages/Profile";
import Register from "./pages/Register";
import Header from "./components/Header"
import '../src/css/bootstrap.css';
import jwtDecode from 'jwt-decode';

export default class App extends React.Component {


    constructor(props) {
        super(props);
        this.state = {
            redirectToHome: false,
            isLog: false,
            isAdmin: false,
            reload: false,
        }
    }

    componentDidMount(){
        if (localStorage.getItem('token')){
            this.setState({isLog:true})
            const {exp,is_admin} = jwtDecode(localStorage.getItem('token'));
            if (is_admin){
                this.setState({isAdmin:true})
            }
            const dateNow = Date.now();
            if (exp * 1000 < dateNow) {
                localStorage.removeItem('token');
            } else {
                setTimeout(() => {
                    localStorage.removeItem('token');
                }, exp * 1000 - dateNow);
            }
        }
    }

    Logout = () => {
        localStorage.removeItem('token')
        if (! localStorage.getItem('token')) {
            return <Redirect to="/"  from="/"/>
        }
    }

    render() {
        if (this.state.reload){
            return document.location.reload(true);
        }
        return (
            <Router>
                <div>
                    <Header isLog={this.state.isLog} isAdmin={this.state.isAdmin} />
                </div>
                <div className="container-fluid mt-3">
                    <Switch>
                        <Route path="/" exact component={Home} />
                        <Route path="/login" exact component={Login} />
                        <Route path="/profile" exact component={Profile} />
                        <Route path="/register" exact component={Register} />
                        <Route path="/logout" exact component={this.Logout} />
                    </Switch>
                </div>
            </Router>
        );
    }


};

index.js 如果需要

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import axios from 'axios';

axios.defaults.baseURL = 'http://127.0.0.1:8000'
if (localStorage.getItem('token')) {
    axios.interceptors.request.use(config => {
        let prefix = '?'
        if (config.url.includes(prefix)) {
            prefix = '&'
        }
        config.url += prefix+'token='+localStorage.getItem('token')
        return config
    })
}


ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

serviceWorker.unregister();

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    BrowserRouter 添加到您的索引文件中,如下所示

    ReactDOM.render(
      <React.StrictMode>
        <BrowserRouter>
           <App />
        </BrowserRouter>
      </React.StrictMode>,
      document.getElementById('root')
    );
    

    然后在您的Login.js 组件中,而不是使用状态来处理页面重定向,只需像这样将新路由推送到历史记录中 history.push('/');

    这也将节省页面重新渲染和您的问题。 尝试这样做

    【讨论】:

    • 这有同样的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 1970-01-01
    • 2019-08-19
    • 2018-12-04
    • 2019-12-29
    • 2020-07-26
    相关资源
    最近更新 更多