【问题标题】:Using connect() from react-redux makes NavLinks from react-router not work?使用 react-redux 中的 connect() 会使 react-router 中的 NavLinks 不起作用?
【发布时间】:2017-10-23 02:38:52
【问题描述】:

我正在学习 redux 并创建了一个 Navbar 组件来处理用户操作。它使用NavLink 将“活动”类添加到我的链接中,以便我可以设置活动链接的样式。当我浏览我的网站时,活动类不会移动,直到我发送一个动作来做出反应(登录/注销是我到目前为止所做的一切)。如果我取出连接的东西并直接使用类组件@987654325 @ 工作正常。将日志添加到 componentDidUpdate 表明在使用 connect 时它没有被调用。

我错过了什么吗?我看到有react-router-redux,但我正在建立一个有趣的网站来学习整个交易,我刚刚开始接触 redux,我不想引入中间件的概念,我绝对不想使用combineReducers,因为此时它只是意味着拥有路由器属性并将其他所有内容推到状态中的“main”之类的东西下。

我正在考虑使用 context 并将整个 redux 状态放在上面...

更新: - 我添加了 react-router-redux,如果我将新的“路由器”添加到我的映射道具,我只能让它更新路由更改。

我有一个 NavbarC 组件类,其渲染方法如下:

render() {
  let { props } = this;

  return <header className="navbar">
    <nav>
      <h1><NavLink to="/" exact>Home</NavLink></h1>
      <NavLink to="/friends">Friends</NavLink>
    </nav>
    <div></div>
    <div className="center-flex-row">
      { props.busy ? <section className="nav-right"><p>working<span className="spacer"></span><span className="fa fa-spin fa-spinner"></span></p></section> :
        props.user ?
          <Logout onSignOutClick={props.onSignOutClick} user={props.user} /> :
          <Login onSignInClick={props.onSignInClick}/>
      }
    </div>
  </header>
}

我使用 connect():

const mapStateToProps = (state) => {
  return { user: state.auth.user, busy: state.auth.busy
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onSignInClick: () => {
      dispatch(userLogin());
    },
    onSignOutClick: () => {
      dispatch(userLogout());
    }
  }
}

const Logout = ({ user, onSignOutClick }) => {
  return <section className="nav-right">
    <button className="btn" onClick={ onSignOutClick }>Sign Out</button>
  </section>
}

const Login = ({ onSignInClick }) => {
  return <section className="nav-right">
    <button className="btn" onClick={ onSignInClick }>Sign In</button>
  </section>
}

export const Navbar = connect(mapStateToProps, mapDispatchToProps)(NavbarC)

【问题讨论】:

  • 您的dispatch 是做什么的?它是否正确更新了状态?
  • 这是有效的,它会在用户登录或注销时更新状态。发生这种情况时,导航栏会更新并突出显示新的NavLink,问题是仅更改链接时它不会更新,因为没有不同的道具,因此连接会阻止组件重新渲染。 NavLinks 必须使用 react-router 提供的上下文中的值,并且 connect 不知道也不关心这些值是否会更改以防止组件重新渲染。

标签: react-router react-redux


【解决方案1】:

我让它以三种方式工作。我认为connect默认忽略道具并替换它们,我基于我的代码的示例没有使用'ownProps'。所以如果我把组件放在一个路由中:

<Route path="/" component={Navbar}/>

并合并我mapStateToProps中的属性:

const mapStateToProps = (state, ownProps) => {
  console.log('mapping state:', state);
  console.log('  ownProps:', ownProps);
  return {
    user: state.main.auth.user,
    busy: state.main.auth.busy,
    ...ownProps
  }
}

这会放入来自 react-router 的 props(历史、位置、匹配)并导致组件更新,因为这些值会随着路由变化而变化。

另一种方法是硬着头皮使用react-router-redux,它会在我的状态上放置一个“路由器”属性,然后我必须将其添加到我的mapStateToProps。即使我不关心值,connect 也会检测到 props 不同并重新渲染组件:

let store = createStore(
  combineReducers({
    main,
    router: routerReducer
  }),
  applyMiddleware(middleware),
}

// in Navbar.js
const mapStateToProps = (state, ownProps) => {
  return {
    user: state.main.auth.user,
    busy: state.main.auth.busy,
    router: state.router
  }
}

我还可以在 options 中指定 pure=false 来连接(),并且每次都应该重新渲染我的组件(至少当我确定更改路线时它会更新正确的 NavLink):

export const Navbar = connect(mapStateToProps, mapDispatchToProps, 
    undefined, { pure: false })(NavbarC)

【讨论】:

  • 谢谢,我也想知道。选项pure 做到了!
【解决方案2】:

解决此问题的最佳和最简单的方法是这样做

export default connect(mapStateToProps, mapDispatchToProps, undefined, { pure: false })(NavbarC)

【讨论】:

  • 尽管这似乎是最快的解决方案并且有效,但很高兴知道最后两个参数的确切用途以及它们是否有任何缩小?
猜你喜欢
  • 1970-01-01
  • 2020-07-05
  • 2017-08-18
  • 1970-01-01
  • 1970-01-01
  • 2018-08-10
  • 2018-11-15
  • 2018-07-24
  • 2018-12-18
相关资源
最近更新 更多