Каков наилучший способ поиска по другому URL в React с использованием Axios? - PullRequest
0 голосов
/ 10 октября 2019

Я пытаюсь разработать приложение для использования API Marvel, используя React с Axios.

Проблема здесь в том, что он нужен мне для поиска по определенному URL, когда в поле ввода ничего не было введено,Но когда пользователь что-то печатает, приложение должно использовать другой URL.

Проблема в том, что единственный способ, с помощью которого я работал, - это установка хука componentDidUpdate . Но это происходит в бесконечном цикле. Я думаю, что это происходит, потому что я обновляю состояние непосредственно в этой точке.

Итак, есть ли лучший способ сделать это? Например, для настройки Axios , чтобы понять эту вариацию, или не возиться с componentDidUpdate , или даже просто обновить состояние, когда пользователь нажимает кнопку ?

Вот мой код:

export default class Main extends Component {
  constructor(props) {
    super(props);
    this.state = {
      heroes: [],
      search: "",
      query: ""
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  componentDidMount() {
    this.loadHeroes();
    console.log("Query state: ", this.state.query);
  }

  componentDidUpdate() {
    console.log("Query state: ", this.state.query);
  }

  loadHeroes = async () => {
    const PUBLIC_KEY = process.env.REACT_APP_PUBLIC;
    const PRIVATE_KEY = process.env.REACT_APP_PRIVATE;
    const timestamp = Number(new Date());
    const hash = md5.create();
    hash.update(timestamp + PRIVATE_KEY + PUBLIC_KEY);

    if (this.state.query === "") {
      await api
        .get(`/characters?ts=${timestamp}&apikey=${PUBLIC_KEY}&hash=${hash}`)
        .then(response =>
          this.setState({ heroes: response.data.data.results })
        );
    } else {
      await api
        .get(
          `/characters?nameStartsWith=${this.state.query}&ts=${timestamp}&apikey=${PUBLIC_KEY}&hash=${hash}`
        )
        .then(response =>
          this.setState({ heroes: response.data.data.results })
        );
    }
  };

  handleChange(e) {
    this.setState({ search: e.target.value });
    console.log(e.target.value);
  }

  handleSubmit(e) {
    console.log("Query state updated: ", this.state.search);
    e.preventDefault();
    this.setState({ query: e.target.value });
  }

  render() {
    const { heroes } = this.state;

    let filteredHeroes = heroes.filter(
      hero => hero.name.toLowerCase().indexOf(this.state.search) !== -1
    );

    return (
      <div>
        <Navbar></Navbar>
        <form onSubmit={this.handleSubmit}>
          <input
            onChange={this.handleChange}
            type="text"
            value={this.state.search}
          />
          <input type="submit" value="Submit" />
        </form>

        <Wrapper>
          {filteredHeroes.map(hero => {
            return (
              <Card key={hero.id} name={hero.name} thumbnail={hero.thumbnail} />
            );
          })}
        </Wrapper>
      </div>
    );
  }
}

1 Ответ

0 голосов
/ 10 октября 2019

Проблема с этим:

componentDidUpdate() {
    this.loadHeroes();
}

- это то, что loadHeroes() изменит state, и это вызовет componentDidUpdate снова. Который будет загружать героев и менять state :). Навсегда.

Возможно, вы захотите повторно только loadHeroes() и только если есть изменения в state.query. Для этого используйте параметр componentDidUpdate prevState:

componentDidUpdate(prevProps, prevState) {
    if (prevState.query != this.state.query) {
        this.loadHeroes();
    }
}

https://reactjs.org/docs/react-component.html#componentdidupdate

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