由于第二个同级组件的更改,如何重新呈现一个同级组件

时间:2018-06-30 16:57:58

标签: reactjs

我有这样的结构:

<Filter>
    <Departure setDeparture={this.setDeparture} />
    <Destination setDestination={this.setDestination} iataDeparture={this.state.departure} />
    <DatePicker setDates={this.setDates} />
    <SearchButton />
</Filter>

现在,我在更新出发组件时尝试重新渲染目标组件。不幸的是,我的代码无法正常工作。

我不使用redux,因为我还不知道,所以我尝试不使用redux的解决方案。

请帮我解决这个问题。

以下是每个组件的代码:

过滤器:

import React, { Component } from 'react';
import axios from 'axios';
import Departure from './Departure';
import Destination from './Destination';
import DatePicker from './DatePicker';
import SearchButton from './SearchButton';

class Filter extends Component {
    constructor(props) {
        super(props);
        this.state = {
            departure: '',
            destination: '',
            startDate: '',
            endDate: '',
            flights: []
        }
    }

    handleSubmit = event => {
        const getFlights = `https://murmuring-ocean-10826.herokuapp.com/en/api/2/flights/from/${this.state.departure}/to/${this.state.destination}/${this.state.startDate}/${this.state.endDate}/250/unique/?limit=15&offset-0`;
        event.preventDefault();
        console.log(this.state.departure);
        console.log(this.state.destination);
        console.log(this.state.startDate);
        console.log(this.state.endDate);

        axios.get(getFlights)
            .then(response => {
                this.setState({ flights: response.data.flights });
                console.log(getFlights);
                console.log(this.state.flights);

                this.props.passFlights(this.state.flights);
            });
    }

    setDeparture = departure => {
        this.setState({ departure: departure });
    }

    setDestination = destination => {
        this.setState({ destination: destination });
    }

    setDates = (range) => {
        this.setState({
            startDate: range[0],
            endDate: range[1]
        });       
    }

    render() {
        return (
            <section className='filter'>
                <form className='filter__form' onSubmit={this.handleSubmit}>
                    <Departure setDeparture={this.setDeparture} />
                    <Destination setDestination={this.setDestination} iataDeparture={this.state.departure} />
                    <DatePicker setDates={this.setDates} />
                    <SearchButton />
                </form>
            </section>
        );
    }
}

export default Filter;

出发:

import React, { Component } from 'react';
import axios from 'axios';

const url = 'https://murmuring-ocean-10826.herokuapp.com/en/api/2/forms/flight-booking-selector/';

class Departure extends Component {
    constructor(props) {
        super(props);
        this.state = {
            airports: [],
            value: '',
            iataCode: ''
        }
    }

    componentDidMount() {
        axios.get(url)
            .then(data => {
                const airports = data.data.airports;
                const updatedAirports = [];
                airports.map(airport => {
                    const singleAirport = [];
                    singleAirport.push(airport.name);
                    singleAirport.push(airport.iataCode);
                    updatedAirports.push(singleAirport);
                    return singleAirport;
                });             
                this.setState({
                    airports: updatedAirports,
                    value: airports[0].name,
                    iataCode: airports[0].iataCode
                });
                this.props.setDeparture(this.state.iataCode);
            });
    }

    handleChange = event => {
        const nameValue = event.target.value;
        const iataCode = this.state.airports.find(airport => {
            return airport[0] === nameValue;
        });

        this.setState({
            value: event.target.value,
            iataCode: iataCode[1]
        });

        this.props.setDeparture(iataCode[1]);
    }    

    render() {
        const departureNames = this.state.airports;
        let departureOptions = departureNames.map((item, index) => {
            return (
                <option value={item[0]} key={index}>{item[0]}</option>
            );
        });

        return (
            <div className='filter__form__select'>
                <select value={this.state.value} onChange={this.handleChange}>
                    {departureOptions}
                </select>
            </div>
        );
    }
}

export default Departure;

目的地:

import React, { Component } from 'react';
import axios from 'axios';

const url = 'https://murmuring-ocean-10826.herokuapp.com/en/api/2/forms/flight-booking-selector/';

class Destination extends Component {
    constructor(props) {
        super(props);
        this.state = {
            routes: {},
            airports: [],
            value: '',
            iataCode: '',
            iataDestinationAirports: '',
            options: []
        }
    }

    componentDidMount() {
        axios.get(url)
            .then(data => {
                const routes = data.data.routes;
                const airports = data.data.airports;                
                const updatedAirports = [];
                airports.map(airport => {
                    const singleAirport = [];
                    singleAirport.push(airport.name);
                    singleAirport.push(airport.iataCode);
                    updatedAirports.push(singleAirport);
                    return singleAirport;
                }); 
                this.setState({
                    routes: routes,
                    airports: updatedAirports,
                });
            })
            .then(() => {
                this.getNamesFromIataCode();
                this.props.setDestination(this.state.iataDestinationAirports);
            });
    }

    componentDidUpdate(prevProps) {
        if (this.props.iataDeparture !== prevProps.iataDeparture) {
            this.setState({ iataCode: this.props.iataDeparture });
            () => this.getNamesFromIataCode();
        };
    }

    handleChange = (event) => {
        const nameValue = event.target.value;      

        const iataCode = this.state.airports.find(airport => {
            return airport[0] === nameValue;
        });        

        this.setState({
            value: event.target.value,
            iataDestinationAirports: iataCode[1]
        });

        this.props.setDestination(iataCode[1]);
    }

    getNamesFromIataCode = () => {
        const iataCode = this.state.iataCode;
        console.log(iataCode);

        const destinationNames = this.state.routes[iataCode];

            let destionationAirports = destinationNames.map(item => {                
                return this.state.airports.filter(el => {                    
                    return el[1] === item;
                });
            });

            let arrayOfOptions = [];
            let firstOptionIataCode = '';
            let firstOptionName = '';
            let destinationOptions = destionationAirports.map((item, index) => {
                console.log(item);

                arrayOfOptions.push(item[0]);

                return (
                    <option value={item[0][0]} key={index}>{item[0][0]}</option>
                );
            });

            firstOptionIataCode = arrayOfOptions[0][1];
            firstOptionName = arrayOfOptions[0][0];

            console.log(firstOptionIataCode);

            this.setState({
                options: destinationOptions,
                iataDestinationAirports: firstOptionIataCode,
                value: firstOptionName
            });

            console.log(this.state.iataDestinationAirports);

            console.log(this.state.options);


            return destinationOptions;

    }

    render() {

        const selectionOptions = this.state.options;

        return (
            <div className='filter__form__select'>
                <select value={this.state.value} onChange={this.handleChange}>
                    {selectionOptions}
                </select>
            </div>
        );

    }
}

export default Destination;

1 个答案:

答案 0 :(得分:0)

正如Tholle所说,您需要提升状态。这是一个示例:

import React from "react";
import ReactDOM from "react-dom";

const A = ({ users, selectUser }) => {
  return (
    <React.Fragment>
      <h1>I am A.</h1>
      {users.map((u, i) => {
        return <button onClick={() => selectUser(i)}>{u}</button>;
      })}
    </React.Fragment>
  );
};

const B = ({ user }) => {
  return <h1>I am B. Current user: {user}</h1>;
};

const C = ({ user }) => {
  return <h1>I am C. Current user: {user}</h1>;
};

class App extends React.Component {
  state = {
    users: ["bob", "anne", "mary"],
    currentUserIndex: 0
  };

  selectUser = n => {
    this.setState({
      currentUserIndex: n
    });
  };

  render() {
    const { users, currentUserIndex } = this.state;
    const currentUser = users[currentUserIndex];

    return (
      <React.Fragment>
        <A selectUser={this.selectUser} users={users} />
        <B user={currentUser} />
        <C user={currentUser} />
      </React.Fragment>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

工作示例here