Reactjs React路由器中未定义React上下文值

Reactjs React路由器中未定义React上下文值,reactjs,react-router,react-context,Reactjs,React Router,React Context,我正在尝试将上下文api用于react路由器。我有一个容器,它的trackList prop中有一个来自mapStateToProps的歌曲列表,我想使用上下文api(无react redux)将其传递给一个名为TrackDetail的无状态组件。正如您将在下面看到的,我使用了useContext钩子和render props模式,但没有成功地从上下文中获取该值 这是Routes文件中的内容: import React,{Component}来自“React”; 从“react Router

我正在尝试将上下文api用于react路由器。我有一个容器,它的trackList prop中有一个来自mapStateToProps的歌曲列表,我想使用上下文api(无react redux)将其传递给一个名为TrackDetail的无状态组件。正如您将在下面看到的,我使用了useContext钩子和render props模式,但没有成功地从上下文中获取该值

这是Routes文件中的内容:

import React,{Component}来自“React”;
从“react Router dom”导入{BrowserRouter as Router,Route,Switch,Redirect};
从“../../containers/TrackList/TrackList”导入轨迹列表;
从“./TrackDetail/TrackDetail”导入TrackDetail;
类路由扩展组件{
render(){
返回(
{this.props.children}
()} />
()} />
);
}
}

导出默认路径首先要提到的是react路由器不应该影响任何东西,因为它只决定呈现什么组件

接下来,上下文使用者必须是上下文提供程序的子级,上下文才能正常工作。正如我在这里看到的,上下文提供者是“TrackList”组件,使用者是“Track”组件,但是这些是同级元素(当您将switch与react-router一起使用时,只有一条路由会渲染,因此您甚至不能将它们渲染为同级元素)

我会尝试将整个路由器包装在上下文提供程序中,因为除了提供反应列表的上下文之外,我看不到任何用法,所以我会删除它。你会得到这样的结果:

class Routes extends Component {
  render() {
    return (
      <TrackListProvider value={{trackList: this.props.trackList}}>
          <div className="Routes">
            <Router>
              <Switch>
                {this.props.children}
                <Route path="/tracks/:id" component={TrackDetail} exact/>
                <Route exact path="/" render={() => (<Redirect to="/tracks" />)} />
                <Route path="*" render={() => (<Redirect to="/tracks" />)} />
              </Switch>
            </Router>
          </div>
        </TrackListProvider>
    );
  }
}
function TrackDetail(props) {
  const { trackList } = useContext(TrackListContext);

  return (
    <div className="container">
      <h3>{trackList}</h3>
    </div>
  );
};

export default TrackDetail;

首先要提到的是,react路由器不应该影响这里的任何内容,因为它只决定渲染哪些组件

接下来,上下文使用者必须是上下文提供程序的子级,上下文才能正常工作。正如我在这里看到的,上下文提供者是“TrackList”组件,使用者是“Track”组件,但是这些是同级元素(当您将switch与react-router一起使用时,只有一条路由会渲染,因此您甚至不能将它们渲染为同级元素)

我会尝试将整个路由器包装在上下文提供程序中,因为除了提供反应列表的上下文之外,我看不到任何用法,所以我会删除它。你会得到这样的结果:

class Routes extends Component {
  render() {
    return (
      <TrackListProvider value={{trackList: this.props.trackList}}>
          <div className="Routes">
            <Router>
              <Switch>
                {this.props.children}
                <Route path="/tracks/:id" component={TrackDetail} exact/>
                <Route exact path="/" render={() => (<Redirect to="/tracks" />)} />
                <Route path="*" render={() => (<Redirect to="/tracks" />)} />
              </Switch>
            </Router>
          </div>
        </TrackListProvider>
    );
  }
}
function TrackDetail(props) {
  const { trackList } = useContext(TrackListContext);

  return (
    <div className="container">
      <h3>{trackList}</h3>
    </div>
  );
};

export default TrackDetail;

开始时没有轨迹列表。它应该被包装在redux中,或者拥有状态本身,并在这些同级中使用该上下文。不过,我在一些帖子中看到,他们并不推荐1个主要的上下文。我明白你的观点,我将使用react-redux,并且只在嵌套的孩子上使用上下文。是的,我不知道曲目列表来自何处,也没有redux体验,所以只是让它保持打开状态。哈哈。我没有听说过任何关于主要上下文的事情,我只使用我的用户authState的上下文,所以我把它放在最高级别上,但是把它放在最低级别上是有意义的,因为一开始没有跟踪列表。它应该被包装在redux中,或者拥有状态本身,并在这些同级中使用该上下文。不过,我在一些帖子中看到,他们并不推荐1个主要的上下文。我明白你的观点,我将使用react-redux,并且只在嵌套的孩子上使用上下文。是的,我不知道曲目列表来自何处,也没有redux体验,所以只是让它保持打开状态。哈哈。我没有听说过任何关于主要上下文的事情,我只使用我的用户authState的上下文,所以我把它放在最高级别上,但是把它放在最低级别上是有意义的