Как передать данные в метод рендеринга в Reaction-native - PullRequest
0 голосов
/ 02 марта 2019

Я пытаюсь отобразить что-то, полученное с помощью graphql, в моем мобильном приложении-реактивном-усилении.Я не могу понять, как передать эти извлеченные данные моему методу рендеринга.Вот исходный кодМне нужно иметь возможность показывать содержимое синглетного объекта внутри рендера.React выдает ошибку, когда я пытаюсь сослаться на this.props.singletour внутри метода render.Еще одна вещь, которую я не могу понять, это как передать параметр, полученный навигацией внутри рендера, в запрос GetTournament graphql.В идеале я хочу, чтобы id: внутри GetTournament содержал navigation.getParam ('itemId', 'NO-ID'), а не жестко закодированный идентификатор.Опять же, response выдает ошибку, когда я получаю доступ к этому параметру в вызове асинхронного метода ... ЛЮБАЯ помощь будет принята с благодарностью !!

 class DetailsScreen extends React.Component {

 async componentDidMount() {
  try {
   const graphqldata = await API.graphql(graphqlOperation(GetTournament, { id: "4e00bfe4-6348-47e7-9231-a8b2e722c990" }))
  console.log('graphqldata:', graphqldata)
  this.setState({ singletour: graphqldata.data.getTournament })
  console.log('singletour:', this.state.singletour)
 } catch (err) {
   console.log('error: ', err)
  }
 }
render() {
/* 2. Get the param, provide a fallback value if not available */
const { navigation } = this.props;
const itemId = navigation.getParam('itemId', 'NO-ID');
const otherParam = navigation.getParam('otherParam', 'some default value');
return (
  <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
    <Text>Details Screen</Text>
    <Text>itemId: {JSON.stringify(itemId)}</Text>
    <Text>otherParam: {JSON.stringify(otherParam)}</Text>

    <Button
      title="Go to Home"
      onPress={() => this.props.navigation.navigate('Home')}
    />
    <Button
      title="Go back"
      onPress={() => this.props.navigation.goBack()}
    />
  </View>
  );
  }
 }

1 Ответ

0 голосов
/ 02 марта 2019

Мне кажется, я знаю, что вы пытаетесь сделать, и этого можно добиться с помощью рефакторинга вашего кода.

Вот что я бы сделал:

  1. Захватите вашпараметры навигации в constructor вашего компонента и сохраните их в state.
  2. Установите начальное значение для SingleTour в состоянии.Установите значение для loaded в состоянии.Значение loaded позволит нам определить, были ли данные возвращены успешно или нет.
  3. Выполните рефакторинг вашего componentDidMount, чтобы он использовал itemId, который теперь хранится в состоянии.
  4. Выполните рефакторинг вашего console.log, который проверяет, установлено ли у вас состояние, поскольку оно не выполняется правильно.
  5. В render извлекайте значения из state и обрабатывайте, были ли данныеloaded или нет.Возможно, вы захотите показать какой-нибудь экран загрузки или вообще не хотите его обрабатывать.

Вот рефакторинг:

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

    // capture the values that you have passed via your navigation in the constructor
    const { navigation } = props;
    const itemId = navigation.getParam('itemId', 'NO-ID');
    const otherParam = navigation.getParam('otherParam', 'some default value');

    this.state = {
      itemId: itemId,
      otherParam: otherParam,
      loaded: false,
      singletour: [] // you don't state what singletour is but you should set a default value here
    };
  }

  async componentDidMount () {
    try {
      // we can now use the state value for itemId as we captured it in the constructor of the component
      const graphqldata = await API.graphql(graphqlOperation(GetTournament, { id: this.state.itemId }));
      console.log('graphqldata:', graphqldata);

      // this is a bad way to access state after it has been set,
      // state is asynchronous and takes time to set.
      // You would need to access set by using the callback method
      // this.setState({ singletour: graphqldata.data.getTournament });
      // console.log('singletour:', this.state.singletour); // <- you should never do this after you setState

      // this is how you should access state after you have set it
      // this will guarantee that the state has been set before the
      // console.log is called, so it should show the correct value of state
      this.setState({
        singletour: graphqldata.data.getTournament,
        loaded: true // we are going to use the loaded value to handle our render
      }, () => console.log('singletour:', this.state.singletour));
    } catch (err) {
      console.log('error: ', err);
      // you may want to show an error message on the screen.
    }
  }
  render () {
    // access the passed parameters from state
    const { itemId, otherParam, loaded, singletour } = this.state;

    if (loaded) {
      // if once the data is loaded we can show screen
      return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Text>Details Screen</Text>
          <Text>itemId: {JSON.stringify(itemId)}</Text>
          <Text>otherParam: {JSON.stringify(otherParam)}</Text>
          <Text>singletour: {JSON.stringify(singletour)}</Text>

          <Button
            title="Go to Home"
            onPress={() => this.props.navigation.navigate('Home')}
          />
          <Button
            title="Go back"
            onPress={() => this.props.navigation.goBack()}
          />
        </View>
      );
    } else {
      // while we are waiting for the data to load we could show a placeholder screen
      // or we could show null. The choice is yours.
      return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Text>Data not loaded</Text>
        </View>
      );
    }
  }
}

Обратите внимание, что componentDidMount вызывается после первого рендеринга, поэтому у нас есть значение loaded в state,Использование loaded позволяет нам обрабатывать то, что представляется пользователю, а не отображать экран, на котором данные еще не закончили загружаться.

Это, безусловно, один из возможных рефакторингов вашего кода.Есть много других способов его рефакторинга.

Вот несколько замечательных статей о настройке состояния

...