Как поместить результат запроса API в значение массива в реагировать родной? - PullRequest
0 голосов
/ 02 февраля 2020

У меня проблема с тем, чтобы поместить результат запроса API в значение массива в моем собственном приложении реакции.

это вызываемая функция

    export function getNewFilmFromApi(page) {
    return fetch(
    'https://api.themoviedb.org/3/discover/movie?api_key=' +
      API_TOKEN +
      '&release_date.gte=2019-10-01&release_date.lte=2019-12-31&language=fr&page=' +
      page,
  )
    .then(response => response.json())
    .catch(error => console.error(error));
}

, и вот как я я пытаюсь поместить возвращенное значение в массив:

    const projects = [
  {
    title: getNewFilmFromApi().then(data => {
      return data.results[0].title;
    }),
    image: require('../Images/background.jpg'),
    author: 'Liu Yi',
    text: 'kkkk',
  },
  {
    title: 'The DM App - Ananoumous Chat',
    image: require('../Images/background.jpg'),
    author: 'Chad Goodman',
    text: 'kjhgfhjkl',
  },
  {
    title: 'Nikhiljay',
    image: require('../Images/background.jpg'),
    author: "Nikhil D'Souza",
    text: 'jjjjjj',
  },
];

Я вижу с console.log, что есть значение для data.results [0] .title, но я не могу поместить его в массив!

Это ошибка, когда я пытаюсь сделать это:

enter image description here

это моя функция рендеринга, и все работает кроме заголовка, который я хочу вернуть из API.

    render() {
    return (
      <Container>
        <AnimatedMask style={{opacity: this.state.opacity}} />
        <Animated.View
          style={{
            transform: [
              {translateX: this.state.pan.x},
              {translateY: this.state.pan.y},
            ],
          }}
          {...this._panResponder.panHandlers}>
          <Project
            title={projects[this.state.index].title}
            image={projects[this.state.index].image}
            author={projects[this.state.index].author}
            text={projects[this.state.index].text}
            canOpen={true}
          />
        </Animated.View>
        <Animated.View
          style={{
            position: 'absolute',
            top: 230,
            left: 0,
            zIndex: -1,
            width: '100%',
            height: '100%',
            justifyContent: 'center',
            alignItems: 'center',
            transform: [
              {scale: this.state.scale},
              {translateY: this.state.translateY},
            ],
          }}>
          <Project
            title={projects[getNextIndex(this.state.index)].title}
            image={projects[getNextIndex(this.state.index)].image}
            author={projects[getNextIndex(this.state.index)].author}
            text={projects[getNextIndex(this.state.index)].text}
          />
        </Animated.View>
        <Animated.View
          style={{
            position: 'absolute',
            top: 240,
            left: 0,
            zIndex: -2,
            width: '100%',
            height: '100%',
            justifyContent: 'center',
            alignItems: 'center',
            transform: [
              {scale: this.state.thirdScale},
              {translateY: this.state.thridTranslateY},
            ],
          }}>
          <Project
            title={projects[getNextIndex(this.state.index + 1)].title}
            image={projects[getNextIndex(this.state.index + 1)].image}
            author={projects[getNextIndex(this.state.index + 1)].author}
            text={projects[getNextIndex(this.state.index + 1)].text}
          />
        </Animated.View>
      </Container>
    );
  }
}

export default connect(mapStateToProps)(Card);

const Mask = styled.View`
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.25);
  z-index: -3;
`;

const AnimatedMask = Animated.createAnimatedComponent(Mask);

const Container = styled.View`
  flex: 1;
  justify-content: center;
  align-items: center;
  background: #f0f3f5;
  margin-top: 80;
`;

const Text = styled.Text``;
var test;

const projects = [
  {
    title: getNewFilmFromApi().then(data => {
      return data.results[0].title;
    }),
    image: require('../Images/background.jpg'),
    author: 'Liu Yi',
    text: 'kkkk',
  },
  {
    title: 'The DM App - Ananoumous Chat',
    image: require('../Images/background.jpg'),
    author: 'Chad Goodman',
    text: 'kjhgfhjkl',
  },
  {
    title: 'Nikhiljay',
    image: require('../Images/background.jpg'),
    author: "Nikhil D'Souza",
    text: 'jjjjjj',
  },
];

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

спасибо!

1 Ответ

1 голос
/ 02 февраля 2020

Способ, которым вы пытаетесь заполнить свой массив результатами от вызова API, не будет работать.

Ваш вызов API является асинхронным и возвращает Promise. Поэтому вам нужно дождаться, пока ваш вызов API завершится до sh и разрешится Promise, а затем обновите массив projects при рендеринге компонента.

Я предлагаю вам сохранить массив projects в состоянии и сделайте вызов API, когда ваш компонент рендерится впервые, как в следующем упрощенном примере:

function getNewFilmFromApi(page) {
  return fetch(`https://jsonplaceholder.typicode.com/todos/1`).then(res =>
    res.json()
  );
}

class MyComponent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      fetchError: false,
      isLoading: true,
      projects: [
        { title: null, author: `Liu Yi` },
        { title: `The DM App - Anonymous Chat`, author: `Chad Goodman` },
        { title: `Nikhiljay`, author: `Nikhil D'Souza` }
      ]
    };
  }

  componentDidMount() {
    const handleResponse = data => {
      const { title } = data;

      // assuming you just want to update
      // the first item in the `projects` array
      const nextProjects = [...this.state.projects];
      nextProjects[0].title = title;

      this.setState({
        projects: nextProjects,
        isLoading: false
      });
    };
    const handleError = err => {
      this.setState({
        apiError: true,
        isLoading: false
      });
    };

    getNewFilmFromApi()
      .then(handleResponse)
      .catch(handleError);
  }

  render() {
    const { apiError, isLoading, projects } = this.state;

    if (isLoading) {
      return <p>Loading...</p>;
    }
    if (!isLoading && apiError) {
      return <p>Error loading projects</p>;
    }
    return <p>{JSON.stringify(projects)}</p>;
  }
}

Вот ссылка на рабочий пример:

...