Как передать реквизит редуктору? ReactJs и Redux - PullRequest
0 голосов
/ 27 апреля 2018

Я борюсь с реакцией-редуксом довольно много часов. Я хочу показать пользователю <Alert />, когда значение isVisible истинно. Я до сих пор плохо понимаю архитектуру редукса. Итак, я пытаюсь передать значение редуктору, но это не работает. Что я делаю не так?

Компонент оповещения:

export default () => {
        return (
            <div className="alert alert-warning">
                <strong>Warning!</strong> Indicates a warning that might need attention.
            </div>
        );
    };

Погодный контейнер:

    renderWeather(cityData) {
        const name = cityData.city.name;
        const temps = _.map(cityData.list.map(weather => weather.main.temp), (temp) => temp - 273);

    return (
        <tr key={name}>
            <td><Chart data={temps} color="orange" units="C" /></td>
            </td>
        </tr>
    )
}
    render() {
        return (
            <div>
                {this.props.isVisible ? null : <Alert /> }
                <table className="table table-hover">
                    <thead>
                        <tr>
                            <th>City</th>
                            <th>Temperature (C)</th>
                        </tr>
                    </thead>
                    <tbody>
                        {this.props.weather.map(this.renderWeather)}
                    </tbody>
                </table>
            </div>
        )
    }
}

function mapStateToProps({ weather, isVisible }) {
    return { weather, isVisible };
}

export default connect(mapStateToProps)(WeatherList);

Индекс редуктора:

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

export default rootReducer;

Разбавление:

export default function (state = [], action) {
    switch (action.type) {
    case FETCH_WEATHER:
        return [...state, action.payload];
    case FETCH_WEATHER_ERROR: 
        return {state, isVisible: false}
    }
    return state;
}

Действие:

export function fetchWeather (city) {
    const url = `${ROOT_URL}&q=${city}`;

    return (dispatch) => {
        axios.get(url);
        .then(({data}) => {
            dispatch({type: FETCH_WEATHER, payload: data});
        })
        .catch((error) => { 
            dispatch({type: FETCH_WEATHER_ERROR, payload: error});
        });
    };
}

Ответы [ 4 ]

0 голосов
/ 27 апреля 2018

Разбить код на меньшие редукторы:

const rootReducer = combineReducers({
  weather: weatherReducer,
  isVisible: isVisibleReducer
});

export default rootReducer;


// reducers:
const weatherReducer = (state = [], action) => {
    if (action.type === FETCH_WEATHER) {
        return action.payload; // data object
    }
    if (action.type === FETCH_WEATHER_ERROR) {
        return action.payload; // error object
    }
    return state;
};

const isVisibleReducer = (state = false, action) => {
    if (action.type === FETCH_WEATHER) {
        return true;
    }
    if (action.type === FETCH_WEATHER_ERROR) {
        return false;
    }
    return state;
};

export { weatherReducer, isVisibleReducer };

Теперь каждая функция редуктора имеет собственную зону управления.

В вашем редукторе у вас смешанный тип состояния. По умолчанию это пустой массив [], но позже вы вернули объект ({state, isVisible: false}). Не делай этого. Вы также уменьшаете weather и isVisible узлов состояния на те же WeatherReducer. Это не правильно, потому что логика изменения этих узлов отличается.

0 голосов
/ 27 апреля 2018

{this.props.isVisible ? null : <Alert /> } следует заменить на {this.props.isVisible ? <Alert /> : null }, потому что когда this.props.isVisible равно true , то только будет видно, но вы делаете это неправильно .. Надеялся, что это помогло

0 голосов
/ 27 апреля 2018

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

Я предлагаю вам также модифицировать combReducers, нет смысла передавать один и тот же редуктор разным свойствам в корневом состоянии.

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

достаточно. Предположим, что ваше состояние - Объект, со свойствами isVisible и weather. Таким образом, ваш редуктор станет.

export default function (state = {isVisible:false, weather:[]}, action) 
 {
  switch (action.type) {
   case FETCH_WEATHER:
     return Object.assign({}, {weather: action.payload, isVisible:false})
   case FETCH_WEATHER_ERROR: 
     return Object.assign({}, {weather:null, isVisible:true})
   }
   return state;
 }

И, наконец, если вы хотите показать, когда isVisible - истина, вы должны

{this.props.isVisible ? <Alert /> : null }

0 голосов
/ 27 апреля 2018

вам нужно действие, которое изменит isVisible э

function changeVisible() {
 return {
   type: FETCH_WEATHER_ERROR
  }
}

и

case FETCH_WEATHER_ERROR: 
   return {...state, isVisible: true}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...