Как передать состояние через контекст в маршрут в React? - PullRequest
0 голосов
/ 11 мая 2018

Каков наилучший способ настроить приложение React с API-интерфейсом контекста, который позволит мне предоставлять некоторые глобальные состояния и методы для каждого маршрута приложения?

Пример. Я хотел бы обработать REST и Auth на верхнем уровне приложения, поэтому я бы хотел, чтобы мои Компоненты вызывали методы запроса на верхнем уровне и чтобы фильтр данных ответов возвращался на уровень Компонентов.

И ... эта архитектура даже действительна в парадигме React? (Я новичок в React)

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

TLDR; CodeSandbox Demo

Хорошо, после небольшой работы я нашел метод решения проблемы (я новичок в React), так что, возможно, это глупое решение.Если да, предоставьте лучший ответ, и я с радостью приму ваш ответ.

Решение

Использование библиотеки Unstated ,Я могу создать оболочку вокруг React Context API, которая обеспечивает внедрение зависимостей.Это позволяет мне создавать экземпляры, которые я могу передать своим компонентам.

Например:

import { Provider, Subscribe } from "unstated";
import CounterContainer from "./counter";

let counterA = new CounterContainer({ initAmount: 4 });
let counterB = new CounterContainer({ initAmount: 8 });

const Red = () => {
  return (
    <Subscribe to={[CounterContainer]}>
      {counter => (
        <div className="red">
          <span>{counter.state.count}</span>
          ...
        </div>
      )}
    </Subscribe>
  );
};

const App = () => (
  <div>
    <Provider inject={[counterA]}>
      <Red />
    </Provider>
    <hr />
    <Provider inject={[counterB]}>
      <Red />
    </Provider>
  </div>
);

Попробуйте демо-версию на CodeSandbox: https://codesandbox.io/s/k3v3wnzrn7

Обертывание React/ Неустановленный контекст как услуга

Я расширил эту идею и создал скелетную службу API.Служба API содержит свойства состояния, такие как loggedIn, а также методы обслуживания, такие как login() и logout().Эти свойства и методы доступны во всем приложении с одним импортом в каждое место, где я хочу использовать службу API.

Я сделал это, поместив Unstated Provider, Subscribe and Instance в службу Api.js.

Например:

Api.js:

import { Provider, Subscribe, Container } from "unstated";

class APIContainer extends Container {
  constructor(props = {}) {
    super();

    this.state = {
      loggedIn: false
    };
  }

  async login() {
    console.log("Logging in");
    this.setState({ loggedIn: true });
  }

  async logout() {
    console.log("Logging out");
    this.setState({ loggedIn: false });
  }
}

const Api = {
  Instance: new APIContainer(),
  Provider,
  Subscribe
};

export default Api;

Теперь я могу включить Api.js в любой другой файл в качестве поставщика,впрыскивая экземпляр, который меня волнует.В этом случае есть только один экземпляр, но я могу предоставить другой экземпляр, если я хочу запустить параллельные тесты.

App.js:

import Api from "./Api";

class App extends React.Component {
  render() {
    return (
      <div>
        <Api.Provider inject={[Api.Instance]}>
          <Routes />
        </Api.Provider>
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

ТогдаЯ могу включить в приложение Api.js и подписаться на то, какой экземпляр был передан по дереву.

Pages / Foo.js:

import Api from "../Api";

class Foo extends React.Component {
  render() {
    return (
      
        {api => (
          
            ? Foo
            
              api.state.loggedIn = {api.state.loggedIn ? "? true" : "? false"}
            
api.login ()}> Login api.logout ()}> Logout )});}} экспорт по умолчанию Foo;

Попробуйте демо-версию CodeSandbox здесь: https://codesandbox.io/s/wqpr1o6w15

Возможно, более опытные разработчики React могут понять, насколько я истребляю React Framework без всякой причины) ...

0 голосов
/ 12 мая 2018

Вы вводите функцию из контекста в реквизиты контейнера: https://reactjs.org/docs/context.html#accessing-context-in-lifecycle-methods

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

<Router>
    <Switch>
        <Route path='/' render={props => <Container {...props} API={API} />} />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...