React Router & Global Context - PullRequest
       0

React Router & Global Context

0 голосов
/ 05 декабря 2018

Я создаю сайт электронной коммерции с помощью React (мой первый проект React) и использую маршрутизатор React для управления своими страницами.

У меня есть следующая древовидная структура компонентов:

<Router>
  <BrowserRouter>
    <Router>
      <withRouter(Base)>
        <Route>
          <Base>
            <BaseProvider>
              <Context.Provider>
                <Header>
                  <PageContent>

Стандартная структура React Router, и с помощью Router я получил следующее:

Base.js

import React, { Component } from 'react';
import { withRouter } from 'react-router';

import { Header } from './Header';
import { Footer } from './Footer';
import Provider from '../../BaseProvider';

class Base extends Component {
  render() {
    return (
      <Provider>
        <Header/>
        <div className="container">{this.props.children}</div>
        <Footer />
      </Provider>
    );
  }
}

BaseProvider.js

import React, { Component, createContext } from 'react';

const Context = createContext();
const { Provider, Consumer } = Context;

class BaseProvider extends Component {
  state = {
    cart: [],
    basketTotal: 0,
    priceTotal: 0,
  };

  addProductToCart = product => {
    const cart = { ...this.state.cart };
    cart[product.id] = product;
    this.setState({ cart, basketTotal: Object.keys(cart).length });
  };

  render() {
    return (
      <Provider
        value={{ state: this.state, addProductToCart: this.addProductToCart }}
      >
        {this.props.children}
      </Provider>
    );
  }
}

export { Consumer };
export default BaseProvider;

По сути, это дает мне шаблон, поэтому я просто использую дочерние страницы без необходимости каждый раз включать верхний и нижний колонтитулы.

Если я хочу использоватьмой глобальный контекст мне приходится импортировать его каждый раз, и кажется, что я сделал что-то не так, так как, конечно, я смогу использовать это на любой странице, так как она экспортируется в BaseProvider?

Если бы я былЧтобы посетить О странице , я получил бы ту же структуру компонентов, но без доступа к потребителю без использования:

import { Consumer } from '../../BaseProvider';

Почему я должен делать это для каждого файла дажехотя он экспортируется и находится на верхнем уровне моего BaseProvider?Кажется, такой шаблон плох, что мне пришлось бы импортировать его примерно в 20 файлов ...

Не импортируя его, я просто получаю:

Line 67:  'Consumer' is not defined  no-undef

Я попытался просто добавитьcontextType to base, но я получаю: Предупреждение: withRouter (Base): Компоненты функций не поддерживают contextType.

Base.contextType = Consumer;

Мне кажется, что я только что реализовал это неправильно, так как этот шаблон должен работать намного лучше.

1 Ответ

0 голосов
/ 05 декабря 2018

Я бы рекомендовал использовать компонент высшего порядка - компонент, который оборачивает другие компоненты с дополнительным состоянием или функциональностью.

const CartConsumer = Component => {
  return class extends React.Component {
    render() {
      return (
        <MyContext.Consumer>
          <Component />
        </MyContext.Consumer>
      )
    }
  }
}

Затем в любом компоненте, где вы хотите его использовать, просто обернитеоператор экспорта:

export default CartConsumer(ComponentWithContext)

Это не исключает полного импорта, но гораздо более минимально, чем непосредственное использование потребителем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...