使用来自react-redux的connect()使得来自react-router的NavLinks不起作用?

时间:2017-05-23 08:36:59

标签: react-router react-redux

我正在学习redux并创建了一个处理用户操作的Navbar组件。它使用NavLink添加'有效'类我的链接所以我可以设置活动链接的样式。当我浏览我的网站时,活动类不会移动,直到我发送动作做出反应(登录/注销是我迄今为止所做的全部工作)。如果我取出连接内容并直接使用类组件NavLinks正常工作。将日志添加到componentDidUpdate表示在使用连接时不会调用它。

我错过了什么吗?我看到那里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)

2 个答案:

答案 0 :(得分:6)

我让它以三种方式工作。我认为连接默认忽略了道具并替换它们,我基于代码的示例没有使用'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-redux,这会在我的状态中添加“路由器”属性,然后我必须将其添加到我的mapStateToProps。即使我不关心值,connect也会检测到道具不同并重新渲染组件:

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):< / p>

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

答案 1 :(得分:3)

解决此问题的最好,最简单的方法是

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