javascript - 处理与 redux 状态管理器 react 的条件

标签 javascript reactjs redux conditional-statements

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

我在列表天气容器的渲染方法中做了一个条件,因此如果没有天气数据,则显示 div,否则显示表格。我的问题是表格从不只显示 div。

这让我很困惑,因为搜索应该更新容器的状态并使用数据重新渲染它,不是吗?我猜我需要在我的 reducer 或状态中添加这个逻辑?我不确定使用哪个或在哪里放置条件来渲染 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>
    );
    }
}

关于javascript - 处理与 redux 状态管理器 react 的条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49522055/

相关文章:

javascript - 更新 XML 数据时使用 ajax 刷新 DIV

javascript - 同时加载多个图像

javascript - 如何在discord.js中使用带有awaitMessages的设置间隔,我想让它连续

node.js - Parceljs 捆绑问题

javascript - 如何在 react 异步调用后测试状态更新和组件重新渲染

javascript - 如何在 react redux 中添加 protected 路由

javascript - react : multiple JSX templates for one single component

reactjs - 在 React/Redux 中更改异步操作完成时的路由

javascript - 为什么setInterval只执行一次?

javascript - 使用 react-router v4 和预取数据进行服务器渲染