上下文 API 将状态提升到更高的组件

Context API bringing state up to higher component

我试图让我的导航栏根据应用所在的页面进行更改,而不必为每个页面创建单独的导航组件。我希望导航栏在用户转到新的 'projects' 页面后发生变化。我这样做的方法是根据 url 参数有条件地呈现导航栏元素。一旦用户点击进入项目页面,就会有一个url参数,比如localhost/project/movie。但是,导航栏组件无法访问 match.params.projectId,只有项目页面组件可以访问它,因为它位于 react-router 的 Route 组件中。因此,我想创建一个存储 url 参数的全局状态,以便我可以在导航栏组件中使用它来有条件地呈现该组件的元素。

最高级别的 App 组件

const App = () => {
  return (
    <div className="app">
      <Header/>
      <Switch>
        <Route exact path="/" component={Home}/>
        <Route exact path="/project/:projectId" component={ProjectOverview}/>
      </Switch>
    </div>
  );
}

下级项目页面组件

const ProjectOverview = ({ match }) => {
    useEffect(() => {
        window.scrollTo(0, 650);
    }, []);

    let project = {};

    if(match.params.projectId === 'movie'){
        project = {
            p: 'Browse your favorite Movies, TV shows, and actors. Search for specific movies, shows or actors by date, rating, region and other categories. Browse the latest and greatest films and to find information about its actors, crew, and reviews. Rate and favorite Movies, TV shows and actors while having access to them through a user account. Login / Authentication.',
            img: 'http://www.technologies.com/images/cloud-summary.png',
            gif: 'https://giphy.com/media/mUgG6FZuWN9V1/giphy.gif',
            list: ['React', 'Redux', 'Hooks', 'TMDB API', 'Sass', 'React Router']
        }
    } else if(match.params.projectId === 'ecommerce'){
        project = {
            p: 'Something else',
            img: 'http://www.technologies.com/images/cloud-summary.png',
            gif: 'https://giphy.com/media/IgASZuWN9V1/giphy.gif',
            list: ['React', 'Redux', 'Hooks', 'TMDB API', 'Sass', 'React Router']
        }
    }

    return(

我知道提供者必须在应用程序组件中环绕 header(navbar) 组件,但需要状态值 (match.params.projectId) 只能在项目页面组件中找到。我想知道如何让提供程序的值成为项目页面组件中 url 参数的任何值。如果我的问题对任何人来说都太混乱了,我会尝试进一步澄清我的问题。谢谢

我不知道这是否是最佳解决方案,但在我必须根据路线更改导航标题的应用程序中,我执行了以下操作:

function App() {

  const [title, setTitle] = useState('');

  return <Router>
      <Navbar title={title} />
       <Switch>
         <Route path="/product/:id" exact render={props => <ProductPage {...props}  setTitle={setTitle} />} />
       </Switch>
       </Router>
}

并且在 ProductComponent 中:

function ProductionComponet({setTitle, match}){
 useEffect(()=>{
   setTitle(`product ${match.params.id}!`)
 },[])
}