Как визуализировать .map () val и key как опору за пределами обратного вызова setState - PullRequest
0 голосов
/ 03 мая 2019

У меня есть этот компонент, который выполняет post request и отображает данные JSON, которые я получаю взамен.На этом ответе я делаю setState и отображаю данные в обратном вызове.Я делаю это из-за асинхронной природы setState.

Я хочу иметь возможность использовать val и key вне его области действия в render(), но я не уверен, как этого добиться.

LoadCard:

class LoadCard extends Component {
  constructor(props) {
    super(props);
    this.state = {
      req: [],
    }
  }

  componentDidMount() {
    axios.post(hostname, {
      request: "?request=getObjects"
    })
      .then(response => {
        this.setState({
          req: JSON.parse(response.data)
        },
          () => this.state.req.objects.map((val, key) => {
            // after mapping what to do here?
          })
        );
      })
      .catch(error => {
        console.log("Error: Card/componentDidMount: " + error);
      });
  }

  render() {
    return (
      <Card key={key} title={val.name} /> /* use val and key here */
    );
  }
}

В рендере компонента я хочу использовать val и key в качестве опоры для Card компонента.

Карта:

class Card extends Component {
  render() {
    return (
      <View key={this.props.key}>
        <Text>{this.props.title}</Text>
      </View>
    );
  }
}

Изменить, чтобы подогнать вопрос к комментарию:

Полученные данные ответа выглядят так:

{
    "objects": [
        {
            "zone_id_1": 151,
            "zone_id_2": null,
            "blocked": "Y",
            "type_id": 1,
            "name": "Alarm chauffeurs@ON=100",
            "output_value": 0,
            "object_id": 1,
            "input_value": 100,
            "last_changed": "2019-04-04T11:36:53",
            "continuously_high_enabled": "N"
        },
        {
            "zone_id_1": 150,
            "zone_id_2": null,
            "blocked": "N",
            "type_id": 1,
            "name": "Alarm office@ON=0",
            "output_value": 0,
            "object_id": 2,
            "input_value": 0,
            "last_changed": "2019-03-26T15:52:01",
            "continuously_high_enabled": "N"
        },

    ]
}

Ответы [ 2 ]

3 голосов
/ 03 мая 2019

Вы должны запустить это внутри вашей функции рендеринга, это будет запущено, когда ваш setState будет завершен.

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

  • состояние по умолчанию: {data: []} // Состояние инициализации - массив
  • on setState ({data: req.objects}) // в вашем ответе axios - массив с Значения

И ваш рендер должен получить к нему доступ

  render() {
      const { data } = this.state;
      const Cards = data.map(({title}, key) => {
          return <Card key={key} title={title} />
      })

      return(
         <View>
           {Cards}
         </View>
      )
    }

Поскольку вы используете состояние «req» внутри функции рендеринга, оно будет автоматически обновляться при обновлении значения req в состоянии.

React - очень мощный инструмент, и я думаю, что каждый должен прочитать о том, как он работает и почему он работает так, как он есть.

1 голос
/ 03 мая 2019

Я думаю, вы неправильно понимаете поведение setState здесь. Не отображать this.state.req.objects в обратном вызове setState.

Вместо этого:

class Card extends Component {
  render() {
    return this.state.req.objects.map((val, key) => (
      <View key={key}>
        <Text>{val.title}</Text>
      </View>
    ));
  }
}

Очевидно, убедитесь, что ваше состояние инициализировано правильно. Например, добавьте objects: [] к req.

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