反应路由器:状态变量更新为setState未被正确传递给Route

时间:2019-01-22 02:34:10

标签: javascript reactjs react-router

因此,我遇到以下问题: 我想允许用户设置我的投资组合的语言。为此,我在初始update组件中为他们提供了两个链接,它们设置了<Language />的状态,然后将用户引导至主屏幕-<App />。问题是,更新后的<Home />没有传递给this.state.language;而是将其具有的初始值向下传递。

我的代码:

<Home />

在加载// <App /> component class App extends React.Component { constructor(props) { super(props) this.state = { language: "none" } } changeLanguage = event => { event.preventDefault() this.setState({ language: event.target.id }, () => { window.location.href = "/home" }) } render() { return ( <BrowserRouter> <div id="app"> <Route exact path="/" render={() => ( <Language changeLanguage={this.changeLanguage} /> )} /> <Route path="/home" component={() => { return <Home language={this.state.language} /> }} /> <Route path="/about" render={() => { return <About language={this.state.language} /> }} /> <Route path="/projects" render={() => { return <Projects language={this.state.language} /> }} /> <Route path="/contact" render={() => { return <Contact language={this.state.language} /> }} /> </div> </BrowserRouter> ) } } // <Language /> component const Language = props => { return ( <div id="language"> <h1>Choose your language.</h1> <div className="lang-options"> <a href="/home" className="lang-link" id="pt_BR" onClick={props.changeLanguage} title="Português Brasileiro" > <img src="https://s3-sa-east-1.amazonaws.com/myhostedfiles.raulf/Images/svg-icons/brazil-flag.svg" alt="A bandeira brasileira. Clique para ter acesso ao site em português." /> </a> <a href="/home" className="lang-link" id="en_US" onClick={props.changeLanguage} title="American English" > <img src="https://s3-sa-east-1.amazonaws.com/myhostedfiles.raulf/Images/svg-icons/usa-flag.svg" alt="The american flag. Click to access the site in english." /> </a> </div> <h1>Escolha seu idioma.</h1> </div> ) } // <Home /> component const Home = (props) => { console.log(props.language) return ( <div id="home"> <div className="bg-filter" /> <Navbar /> <TypedIntro /> <LinkBox /> </div> ) } 组件时,<Home />console.log(props.language)记录到控制台,该初始值被设置为none。谁能向我解释为什么不更新以及如何解决?

4 个答案:

答案 0 :(得分:1)

设置window.location.href将刷新页面。那会失去你所有的状态。将您的<a>标签更改为使用react-router <Link to="/home">标签。

这里有一个CodeSandbox可以帮助说明发生了什么:

Edit yk1n96ynmz

答案 1 :(得分:0)

您是否尝试过探索this作为解决方案?您将拥有一个文件,可以在其中定义每种语言的键,并传递一个i18n对象以访问每个键。这是一种反模式,因为您正在尝试使用多个组件来突变状态。

答案 2 :(得分:0)

您遇到了问题,因为您使用的是windows.location.href,它将刷新应用程序。之后,您将获得该应用程序的新实例,并且将丢失该应用程序的状态。这就是您在控制台中获得初始状态的原因。

windows.location.href更改为this.props.history.push(),但您需要使用'react-router-dom'中的App HOC包装withRouter组件。我在某些地方更改了您的代码,请检查一下。并尝试使用Link标签代替a标签。

import { BrowserRouter , Route,  withRouter} from "react-router-dom";
.....

class App extends React.Component {
  constructor(props) {
      super(props)
      this.state = {
          language: "none"
      }
  }

  changeLanguage = event => {
      event.preventDefault()
      // react-router passes "history" as props
      this.setState({ language: event.target.id }, () => this.props.history.push('/home'))
  }

  render() {
      return (

          <div id="app">
            <Route
              exact
              path="/"
              render={() => (
                  <Language changeLanguage={this.changeLanguage} />
              )}
            />
            <Route
              path="/home"
              component={() => {
                  return <Home language={this.state.language} />
              }}
            />            
           </div>
      )
  }
}

// wrapping App component with "withRouter" HOC
const RouterApp = withRouter(App)

// <NewApp /> Component
// you need to do this because component wrapped inside
// "withRouter" HOC must be inside "Router" component
const NewApp = () => {
 return <BrowserRouter>
        <RouterApp />
  </BrowserRouter>
}

// <Language/> Component
const Language = props => {
  return (
      <div id="language">
          <h1>Choose your language.</h1>
          <div className="lang-options">
              <p
                  className="lang-link"
                  id="pt_BR"
                  onClick={props.changeLanguage}
                  title="Português Brasileiro"
              >
                  Português
              </p>
              <p
                  className="lang-link"
                  id="en_US"
                  onClick={props.changeLanguage}
                  title="American English"
              >
                  American
              </p>
          </div>
          <h1>Escolha seu idioma.</h1>
      </div>
  )
}   

// <Home Component/>
const Home = (props) => {
  console.log(props.language)
  return (
      <div id="home">
          Home Component
          <p>Language: {props.language}</p>
      </div>
  )
}

// render NewApp component
ReactDOM.render(<NewApp />, document.getElementById('root'));

答案 3 :(得分:0)

您应该使用<Link to='/home'>而不是window.location.href =“ / home”。

这将重新加载页面并重新加载组件。还会禁用react作为SPA的功能。