我正在使用react / redux从天气api构建一个简单的天气检索页面。我的问题是与Redux状态管理器反应来处理条件。我有一个表格,在输入城市时显示天气信息。在进行查询之前,此表的标题是可见的。我想添加一个条件来用div替换整个表,该div告诉用户搜索城市。进行搜索时,我要呈现表格。

我在列表天气容器的render方法中设置了条件,因此,如果没有天气数据显示,则div否则显示表格。我的问题是表格永远不会只显示div。

这使我感到困惑,因为搜索应该更新容器的状态并用数据重新呈现它,不是吗?我猜我需要在我的reducer或state中添加此逻辑吗?我不确定如果有数据或在进行搜索且有数据的情况下使用哪个条件或在哪里放置有条件的条件来渲染div。

//  search container
class SearchBar extends Component {
constructor(props) {
    super(props);

    this.state = { term: '' };
    this.onInputChange = this.onInputChange.bind(this);
    this.onFormSubmit = this.onFormSubmit.bind(this);
}

onInputChange(event) {
   this.setState({ term: event.target.value });
}

onFormSubmit(event) {
    event.preventDefault();
    this.props.fetchWeather(this.state.term);
    this.setState({ term : ''});
}

render() {
    return (
        <form onSubmit={this.onFormSubmit}
                className={styles.search}>
            <div className={styles.wrap}>
                <input  value={ this.state.term }
                        onChange={ this.onInputChange }
                        placeholder="Enter US cities for a forecast"
                        className={styles.wrap__input}/>
                <button type="submit" className={styles.wrap__btn}>search</button>
            </div>
        </form>
    )
  }
}

function MapDispatchToProps(dispatch) {
return bindActionCreators({ fetchWeather }, dispatch);
}

export default connect(null, MapDispatchToProps)(SearchBar);


// weather list container
class ListWeather extends Component {
renderWeather(data){

if(!data) {
    let id = Math.round(Math.random() * 100);
    return  (
        <tr key={ id }>
            <td className={styles.table__data_error} colspan="5">Please enter a valid US City.</td>
        </tr>
    )
} else  {
    const temps = data.list.map(weather => weather.main.temp * 9/5 - 459.67);
    const pressures = data.list.map(weather => weather.main.pressure);
    const humidities = data.list.map(weather => weather.main.humidity);
    const avg = "AVG";

        return (
            <tr key={ data.city.id }>
                <td className={styles.table__data_name}>{ data.city.name }</td>
                <td><Chart color="red" data={temps} />{avg} Temperature</td>
                <td><Chart color="green" data={humidities} />{avg} Humidity</td>
                <td><Chart color="blue" data={pressures} />{avg} Pressure</td>
            </tr>
        )
    }
}

render(){

    if(!this.props.weather.data) {
        return (
            <div className={styles.start}>Enter a US City to get started.</div>
        )
    } else {
    return (
        <table className={styles.table}>
        <thead className={styles.table__head}>
            <tr className={styles.table__row}>
                <th className={styles.table__rowhead}>City</th>
                <th className={styles.table__rowhead}>Temp</th>
                <th className={styles.table__rowhead}>Humidity</th>
                <th className={styles.table__rowhead}>Pressure</th>
            </tr>
        </thead>
        <tbody className={styles.table__body}>
            { this.props.weather.map(this.renderWeather)}
        </tbody>
    </table>
    );
    }
}
}

function MapStateToProps({ weather }) {
return { weather };
}

export default connect(MapStateToProps)(ListWeather)


// actions / index.js
import axios from 'axios';

const API_KEY='b60aa70986cac3edb4248b5569b74a92';
const ROOT_URL=`http://api.openweathermap.org/data/2.5/forecast?
appid=${API_KEY}`;

export const FETCH_WEATHER = 'FETCH_WEATHER';

export function fetchWeather(city) {
const url = `${ROOT_URL}&q=${city},us`;
const request = axios.get(url);

return {
    type: FETCH_WEATHER,
    payload: request
};
}

// reducers/reducer_weather.js
import { FETCH_WEATHER } from '../actions/index';

export default function(state=[], action) {
switch (action.type) {
    case FETCH_WEATHER:
        // return state.concat([ action.payload.data ]);
        return [ action.payload.data, ...state ]
    default : return state;
}
return state;
}

//reducers/index.js
import { combineReducers } from 'redux';
import WeatherReducer from './reducer_weather';

const rootReducer = combineReducers({
weather: WeatherReducer
});

export default rootReducer;

最佳答案

更改您的检查以检查this.props.weather的长度是否大于0。由于this.props.weather.data是一个数组,因此看起来this.props.weather永远不会存在:

render(){

    if(!this.props.weather.length) {
        return (
            <div className={styles.start}>Enter a US City to get started.</div>
        )
    } else {
    return (
        <table className={styles.table}>
        <thead className={styles.table__head}>
            <tr className={styles.table__row}>
                <th className={styles.table__rowhead}>City</th>
                <th className={styles.table__rowhead}>Temp</th>
                <th className={styles.table__rowhead}>Humidity</th>
                <th className={styles.table__rowhead}>Pressure</th>
            </tr>
        </thead>
        <tbody className={styles.table__body}>
            { this.props.weather.map(this.renderWeather)}
        </tbody>
    </table>
    );
    }
}

07-24 09:38
查看更多