我在React中有一个重定向问题

时间:2019-07-23 10:52:57

标签: javascript reactjs web

我是新来的反应者,我正在创建一个简单的Contact Manager App,我有联系人和addContact组件,这些组件以不同的路径分开。 当我添加联系人时,它会添加到本地存储中,而联系人组件正在从本地存储中获取联系人列表。 当我添加联系人并重定向到联系人页面时,除非手动刷新页面,否则不会显示新联系人的问题。

我尝试过:

this.props.history.push('/');

这也是

window.location.href=window.location.hostname;

如果上一个链接是addContact链接,我创建了一个刷新页面的功能,

这是App组件代码:

import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Navbar from './components/navbar';
import Contacts from './components/contacts';
import About from './components/pages/about';
import AddContact from './components/pages/addContact'
import NotFound from './components/pages/notFound'

function getContactsLS() {
    let contacts;
    if (localStorage.getItem('contacts') === null) {
        contacts = [];
    }
    else {
        contacts = JSON.parse(localStorage.getItem('contacts'));
    }
    contacts = Array.from(contacts);
    return contacts;
}


class App extends React.Component {
    contactsLS = getContactsLS();

    render() {
        return (
            <Router>
                <Navbar />
                <div className="container">
                    <Switch>
                        <Route exact path="/add-contact" component={AddContact} />
                        <Route exact path="/" component={() => <Contacts contacts={this.contactsLS} />} />
                        <Route exact path="/about" component={About} />
                        <Route component={NotFound}/>
                    </Switch>
                </div>
            </Router>
        )
    }
}

export default App
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

这是addContact函数:

addContactEvent = () =>{
        let contacts;
        if(localStorage.getItem('contacts')===null)
            contacts=[];
        else{
            contacts=JSON.parse(localStorage.getItem('contacts'));
        }
        contacts=Array.from(contacts);
        console.log(contacts);
        this.setState({key:contacts.length});
        const contact = {
            key : contacts.length,
            name: this.state.name,
            email:this.state.email,
            phone:this.state.phone
        }
        contacts.push(contact);
        localStorage.setItem('contacts', JSON.stringify(contacts));

        //redirection
        //this.props.history.push('/');
        window.location.href=window.location.hostname;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>

2 个答案:

答案 0 :(得分:0)

您可以使用<Redirect>包中的react-router-dom组件。要使其正常工作,请首先设置setState,将重定向设置为false。

this.state = {
  redirect: false
}

完成addContact操作后,请更新状态

this.setState({
  redirect: true
})

AddContact组件内部,状态将决定是否必须显示实际组件或重定向到附加路径。 像这样:

import {Redirect } from 'react-router-dom';
class AddContact extends React.Component {
  //Add the initial state
  // addContact Operation
  render(){
    if(this.state.redirect)
      return <Redirect to="/" />
    return (
       //The markup for AddContact
    )

  }
}

答案 1 :(得分:0)

感觉就像您希望将联系人作为州的一部分。在这种情况下,代码将是:

state = { contactLS: getContactsLS()}

但是当我们从localStorage调用值时,一个更合适的位置可能是 componentDidMount()方法。从反应docs

  

避免在广告中引入任何副作用或订阅   构造函数。对于这些用例,请改用componentDidMount()。

那么代码就是

componentDidMount(){
    const contacts =  getContactsLS()
    this.setState({ contacsLS: contacts })
}

别忘了更改为 this.state.contactsLS

<Route exact path="/" component={() => <Contacts contacts={this.state.contactsLS} />} />

====

PS
我可以在现有代码中看到的另一个问题是滥用组件构造函数。
这不是很明显,但是

contactsLS = getContactsLS();

等效于

constrcutor(){
   this.contactLS = getContactLS();
}

从react文档中我们read

  

通常,在React中,构造函数仅用于两个目的:
  -通过将对象分配给this.state来初始化本地状态。
  - 捆绑   实例的事件处理程序方法。