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

Jas*_*aat 2 react-router react-redux

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

我错过了什么吗?我看到有反应路由器还原,但我正在建立一个有趣的网站,以了解整个交易,我只是开始得到redux,我不想引入中间件的概念,我绝对不想要使用,combineReducers因为在这一点上它只是意味着拥有路由器属性并在州内的"主"之类的东西推送其他所有东西.

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

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

我有一个NavbarC带有这样的render方法的组件类:

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>
}
Run Code Online (Sandbox Code Playgroud)

我使用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)
Run Code Online (Sandbox Code Playgroud)

Jas*_*aat 6

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

<Route path="/" component={Navbar}/>
Run Code Online (Sandbox Code Playgroud)

并合并我的属性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
  }
}
Run Code Online (Sandbox Code Playgroud)

这会放入来自react-routers(历史,位置,匹配)的道具并导致组件更新,因为这些值会在路由更改时发生更改.

另一种方法是咬住子弹并使用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
  }
}
Run Code Online (Sandbox Code Playgroud)

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

export const Navbar = connect(mapStateToProps, mapDispatchToProps, 
    undefined, { pure: false })(NavbarC)
Run Code Online (Sandbox Code Playgroud)


Mor*_*s S 5

解决这个问题的最好和最简单的方法是这样做

export default connect(mapStateToProps, mapDispatchToProps, undefined, { pure: false })(NavbarC)
Run Code Online (Sandbox Code Playgroud)

  • 尽管这似乎是最快的解决方案并且有效,但很高兴知道最后两个参数的具体用途以及它们是否有任何缩小? (3认同)