状态更改时,React组件不会重新渲染

时间:2018-09-23 19:11:54

标签: javascript json reactjs api

我正在制作一个React应用,用户可以在其中输入机场的标识符,该应用将从Web API获取相应的天气数据并将其显示在表格中(例如:CYOW-> {{3 }})。我已经知道,“ url”状态(指定用户搜索的机场的API端点)在他们输入值时正在更新,但是当该状态更改时,组件不会重新呈现,因此我的表没有更新。我在这里做错了什么?对不起,代码不好,这是我第一次使用React + JS。谢谢。

import React, { Component } from 'react';
import {Icon, Label, Menu, Table, Form, Button} from 'semantic-ui-react';

export default class Stationsearch extends React.Component {

    constructor(props){
        super(props);
        this.state = {
            url: 'http://avwx.rest/api/metar/CYOW',
            data: {},
            Station: '',
            Timestamp: '',
            Time: '',
            FlightRules: '',
            Temperature: '',
            Dewpoint: '',
            Visibility: '',
            WindDir: '',
            WindGust: '',
            WindSpeed: '',
            WindVar: [],
            CloudList: [],
            Raw: '',
            userInput: '',
        };

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

    componentDidMount(){

        fetch(this.state.url)
        .then(d => d.json())
        .then(d => {
            this.setState({
                data: d, 
                Station: d.Station,
                Timestamp: d.Meta.Timestamp,
                Time: d.Time,
                FlightRules: d["Flight-Rules"],
                Temperature: d.Temperature,
                Dewpoint: d.Dewpoint,
                Visibility: d.Visibility,
                WindDir: d["Wind-Direction"],
                WindGust: d["Wind-Gust"],
                WindSpeed: d["Wind-Speed"],
                WindVar: d["Wind-Variable-Dir"],
                CloudList: d["Cloud-List"],
                Raw: d["Raw-Report"],
            })
        })
    }

    handleChange(event){
        this.setState({userInput: event.target.value});
    }

    handleSubmit(event){
        this.setState({url: getUrl(this.state.userInput)});
        event.preventDefault();
    }

render(){
    return (
        <div>
            <Form onSubmit={this.handleSubmit}>
                <Form.Field>
                    <Label>Station ID</Label>
                    <input type="text" placeholder="ex: CYOW" onChange={this.handleChange} />
                </Form.Field>
                <Button type='submit'>Search</Button>
            </Form>

            <Table celled striped textAlign="center" color="teal" key="teal" inverted className='table'>
                <Table.Header>
                    <Table.Row>
                    <Table.HeaderCell>Type</Table.HeaderCell>
                    <Table.HeaderCell>Value</Table.HeaderCell>
                    </Table.Row>
                </Table.Header>

                <Table.Body>
                    <Table.Row>
                        <Table.Cell>Station</Table.Cell>
                        <Table.Cell>{ this.state.Station }</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <Table.Cell>Timestamp</Table.Cell>
                        <Table.Cell>{ this.state.Timestamp }</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <Table.Cell>Zulu</Table.Cell>
                        <Table.Cell>{ this.state.Time }</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <Table.Cell>Flight-Rules</Table.Cell>
                        <Table.Cell>{ this.state.FlightRules }</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <Table.Cell>Temperature</Table.Cell>
                        <Table.Cell>{ this.state.Temperature }</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <Table.Cell>Dewpoint</Table.Cell>
                        <Table.Cell>{ this.state.Dewpoint }</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <Table.Cell>Visibility</Table.Cell>
                        <Table.Cell>{ this.state.Visibility }</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <Table.Cell>Wind-Direction</Table.Cell>
                        <Table.Cell>{ this.state.WindDir }</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <Table.Cell>Wind-Speed</Table.Cell>
                        <Table.Cell>{ this.state.WindSpeed }</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <Table.Cell>Wind-Gust</Table.Cell>
                        <Table.Cell>{ this.state.WindGust }</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <Table.Cell>Wind-Variable-Dir</Table.Cell>
                        <Table.Cell>{ this.state.WindVar }</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <Table.Cell>Clouds</Table.Cell>
                        <Table.Cell>{ getCloudString(this.state.CloudList) }</Table.Cell>
                    </Table.Row>
                </Table.Body>
            </Table>
        </div>
    )}
}

function getCloudString(cloudList) {

    var list = "";

    for (var i=0; i < cloudList.length; i++){
        if (i+1 < cloudList.length){
            list += cloudList[i][0] + " " + cloudList[i][1] + ", ";
        }
        else{
            list += cloudList[i][0] + " " + cloudList[i][1];
        }
    }
    return list;
}

function getUrl(stationID){
    var url = 'http://avwx.rest/api/metar/';
    var id = stationID.toUpperCase();
    url += id;
    return url;
}

3 个答案:

答案 0 :(得分:3)

听起来fetch发生更改时,您希望发出另一个url请求。在当前代码中,您仅在fetch内执行componentDidMount,仅在首次创建组件时才调用一次。相反,应该在url方法中或在componentDidUpdate内部更改handleSubmit时调用它。

答案 1 :(得分:0)

您仅在组件状态下更新URL,而不获取该站ID的数据。更新工作站ID之后,您还需要获取数据并在状态下对其进行更新。您的组件正在重新渲染,但是由于任何数据都没有更改,因此您的视图也没有更新。

  fetchData = () => {
    fetch(this.state.url)
      .then(d => d.json())
      .then(d => {
        this.setState({
          data: d,
          Station: d.Station,
          Timestamp: d.Meta.Timestamp,
          Time: d.Time,
          FlightRules: d["Flight-Rules"],
          Temperature: d.Temperature,
          Dewpoint: d.Dewpoint,
          Visibility: d.Visibility,
          WindDir: d["Wind-Direction"],
          WindGust: d["Wind-Gust"],
          WindSpeed: d["Wind-Speed"],
          WindVar: d["Wind-Variable-Dir"],
          CloudList: d["Cloud-List"],
          Raw: d["Raw-Report"]
        });
      });
  };

  componentDidMount() {
    this.fetchData();
  }

  handleSubmit(event) {
    this.setState({ url: getUrl(this.state.userInput) }, () => {
      this.fetchData();
    });
    event.preventDefault();
  }

这是工作代码的链接。我已将默认工作站ID设置为OMDB,并且当您搜索CYOW数据时会被更新。

https://codesandbox.io/s/3mqp187w1

答案 2 :(得分:0)

代码运行正常,提交时您不会再次获取!

这是一个有效的版本:

https://codesandbox.io/s/k902vrw7k7

还请确保验证用户输入,因为到目前为止,当用户输入无效的电台时,您将崩溃。

相关问题