Как пройти магазин Mobx в качестве реквизита для реагирования на композицию - PullRequest
0 голосов
/ 10 февраля 2020

У меня есть это приложение, которое использует mobx, в нем есть компонент под названием «Списки», который использует какое-то состояние от mobx для отображения списка элементов.

То, как это сейчас происходит, заключается в том, Listings Компонент получает необходимые данные (store.restaurantResults[store.selectedFood]) изнутри, используя хранилище mobx следующим образом:

const Listings = () => {
  const store = React.useContext(StoreContext);

  return useObserver(() => (
    <div className="pa2">
        {store.restaurantResults[store.selectedFood] &&
          store.restaurantResults[store.selectedFood].map((rest, i) => {
            return (
              <div key={i} className="pa2 listing">
                <p>{rest.name}</p>
              </div>
            );
          })}
    </div>
  ));
};

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

Как правильно это сделать? Прямо сейчас мой App выглядит следующим образом, где он обернут вокруг storeProvider:

function App() {
  return (
    <StoreProvider>
      <div className="mw8 center">
        <Header title="EasyLunch" subTitle="Find Pizza, Burgers or Sushi in Berlin the easy way"/> 
        <FixedMenu menuItem1={"Pizza"} menuItem2={"Burger"} menuItem3={"Sushi"} />
        <p className="b tc pt3">or...</p>
        <Search /> 
        <Listings />
      </div>
    </StoreProvider>
  );
}

Моя идея состоит в том, чтобы извлечь что-либо внутри StoreProvider в другой компонент, который имеет хранилище, и возвращает JSX через useObserver, чтобы я мог получить доступ к магазину и затем передать то, что мне нужно, в качестве реквизита для других компонентов. как это:

const Wapper = () => {
  const store = React.useContext(StoreContext);
  return useObserver(() => (
    <div className="mw8 center">
      <Header title="EasyLunch" subTitle="Find Pizza, Burgers or Sushi in Berlin the easy way" />
      <FixedMenu menuItem1={"Pizza"} menuItem2={"Burger"} menuItem3={"Sushi"} />
      <p className="b tc pt3">or...</p>
      <Search />
      <Listings listings={store.restaurantResults[store.selectedFood]} />
    </div>
  ))
}

А затем в компоненте листингов измените жестко закодированный store.restaurantResults[store.selectedFood] внутри, чтобы использовать пропуска, который проходит сейчас, который называется listigs, например:

const Listings = ({listings}) => {
  const store = React.useContext(StoreContext);

  return useObserver(() => (
    store.loading
      ? <Loading />
      : <div className="pa2">
        <div className="flex flex-wrap">
          {listings &&
            listings.map((rest, i) => {
              return (
                <div key={i} className="pa2 listing">
                  <img className='object-fit' src={rest.image_url} alt="restuarant" />
                  <p>{rest.name}</p>
                  <p>{rest.location.address1}</p>
                </div>
              );
            })}
        </div>
      </div>
  ));
};

И это работает, но верно ли это go об этом?

Ответы [ 2 ]

0 голосов
/ 11 февраля 2020

Поскольку <Listings/> может быть предоставлено с listing и loading, вы можете:

const Listings = ({listings, loading}) => {
  if(loading) return <Loading />
  return (
    <div className="pa2">
      <div className="flex flex-wrap">
        {listings && listings.map((rest, i) => {
          return (
            <div key={i} className="pa2 listing">
              <img className='object-fit' src={rest.image_url} alt="restuarant" />
              <p>{rest.name}</p>
              <p>{rest.location.address1}</p>
            </div>
          );
        })}
      </div>
    </div>
  );
}

Нет используемых наблюдений, useObservable не требуется.

Вы хотите useObservables на store для списков, то нет причин оборачивать все компоненты useObservable. Вы должны обернуть только <Listings/>.

0 голосов
/ 10 февраля 2020

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

class Store {
  @observable myVar
}

global.store = new Store()

А в своих компонентах я просто использую его:

@observer
export default class MyComponent extends React.Component {
  constructor () {
    super()
    store.myVar = 0
  }

  setMyVar (a) {
    store.myVar += 1
  }

  render () {
    return <button onClick={this.setMyVar}>
      Clicked {store.myVar} times
    </button>
  }
}
...