Контекстный API, передающий состояние вышестоящему компоненту

Я пытаюсь изменить свою панель навигации в зависимости от того, на какой странице находится приложение, без необходимости создавать отдельные компоненты навигации для каждой страницы. Я хочу, чтобы панель навигации менялась, когда пользователь переходит на новую страницу «проектов». Я бы сделал это условно, отображая элементы панели навигации в зависимости от параметра URL. Как только пользователь щелкнет, чтобы перейти на страницу проекта, появится параметр URL, например localhost/project/movie. Однако компонент панели навигации не имеет доступа к match.params.projectId, доступ к нему есть только у компонента страницы проекта, поскольку он находится внутри компонента Route из react-router. Поэтому я хочу создать глобальное состояние, в котором хранится параметр url, чтобы я мог использовать его в компоненте панели навигации для условной визуализации элементов этого компонента.

Компонент приложения высшего уровня

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-адреса в компоненте страницы проекта. Я постараюсь уточнить свой вопрос, если он покажется кому-то слишком запутанным. Спасибо


person albert_anthony6    schedule 01.04.2020    source источник


Ответы (1)


Я не знаю, лучшее ли это решение, но в приложении, где мне приходилось менять заголовок навигации в зависимости от маршрута, я сделал следующее:

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}!`)
 },[])
}
person Gonzalo Gras Cantou    schedule 01.04.2020
comment
Похоже, это сработает. Я попытаюсь реализовать это и посмотреть, работает ли это для моего приложения. Я отмечу это как ответ, когда все заработает, спасибо - person albert_anthony6; 02.04.2020