Próbuję napisać wszystkie moje komponenty jako czyste funkcje, ale teraz wpadam w kłopoty. Mam komponent, który wygląda nieco jak poniżej. Problem polega na tym, że wynik wniosku Ajax powoduje, że derbender, co powoduje kolejne żądanie Ajax, a tam masz nieskończoną pętlę. Jak właściwie obsługiwać?

const PageProductFunnel = function (props) {
  const agent = ajaxagent;
  var list = [];

  agent.get(`https://mylist.com/${productSKU}`).then((res) => {
    list = res.data;
  });

  return (
    <div>
      <div className="cell">
        <article className="article">
          <h1 className="article-title">{product.name}</h1>
          <FunnelStep {...props} list={list} />
          <ButtonAddToCart product={product} />
        </article>
      </div>
    </div>
  );
};
3
Jasper Kennis 28 czerwiec 2017, 16:21

4 odpowiedzi

Najlepsza odpowiedź

Istnieje kilka podejść, które możesz wziąć:

  1. Fetch Data Async Globaly, a nie wewnątrz renderowania komponentu
  2. Nie używaj czystej funkcji dla tego komponentu i zacznij async do metod cyklu życia
1
Davorin Ruševljan 28 czerwiec 2017, 13:49

Lepszy hak cyklu życia do wykonania połączenia AJAX jest ComponentDididMount (). Jeśli jesteś tak specyficzny do użycia Czysty komponent, możesz użyć w czystym komponencie.

class Sample extends PureComponent{
  //react implement ShouldComponentUpdate for us which does shallow comparison
  componentDidMount(){
     //api call here
  }
 }

Ale nie możesz zbudować aplikacji reagującej za pomocą tylko Purecomponent, ponieważ jeśli jest przypadek, w którym nie można zatrzymać cyklu życia Trway Aktualizacja, sprawdzając stan, nie można tego zrobić za pomocą Purecomponent, ponieważ czysty komponent robi tylko płytkie Sprawdzanie nas i sprawdza wszystkie stany w komponencie.

Powinniśmy równoważyć państwowy, Purecomponent, bezpaństwowcy wśród projektu.

0
zakir 19 luty 2019, 12:15

Edytuj Przeczytaj komentarze. Po kilku rozważań postanowiłem wdrożyć pierwszą sugestię Davorin Ruševljans. Moje własne rozwiązanie działa, ale jego jest lepsze.


Dzięki za sugestie, ale naprawdę nie rozwiążą problemu. Cały mój kod jest tak daleko czysty, a ja naprawdę chcę się z tym trzymać. Dokonanie połączenia na poziomie globalnym nie zmienia niczego w moim przypadku, ponieważ odpowiedź nadal spowoduje renderowanie.

Zmieniłem kod, aby lista była częścią państwa (używam Redux). Tylko jeśli lista jest pusta, wykonuję połączenie Ajax. Ilekroć wiem, że spodziewam się, że nowe dane, wyczyczę starej listy, zanim strona znów sprawia.

if (props.list.length === 0) {
  agent.get(`https://mylist.com/${productSKU}`).then((res) => {
    props.setList(res.data);
  });
}
0
Jasper Kennis 29 czerwiec 2017, 13:33

Musisz użyć elementów stateful.

class PageProductFunnel extends React.Component {
  state = {
    "list": []
  }

  componentWillMount () {
    agent.get(`https://mylist.com/${productSKU}`).then((res) => {
      this.setState({list:res.data})
    });
  }

  render () {
    return (
      <div>
        <div className="cell">
          <article className="article">
            <h1 className="article-title">{product.name}</h1>
            <FunnelStep {...props} list={this.state.list} />
            <ButtonAddToCart product={product} />
          </article>
       </div>
      </div>
    );
  }
};
0
Harkirat Saluja 28 czerwiec 2017, 13:51