简体   繁体   English

如何将道具传递给减速器? ReactJs和Redux

[英]How to pass props to reducer? ReactJs and Redux

I'm struggling with react-redux thing quite a lot of hours. 我在很多时候都在用react-redux挣扎。 I want to show to user <Alert /> when isVisible value is true. isVisible值为true时,我想向用户显示<Alert /> I'm still don't understand well architecture of redux. 我仍然不太了解redux的体系结构。 So, I'm trying to pass value to reducer but it doesn't work. 因此,我正在尝试将价值传递给减速器,但它不起作用。 What I'm doing wrong? 我做错了什么?

Alert component: 警报组件:

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

Weather container: 天气容器:

    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);

Index reducer: 索引减少器:

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

export default rootReducer;

Reducer: 减速器:

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;
}

Action: 行动:

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});
        });
    };
}

You have to decide if your state need to be an array or an object. 您必须决定您的状态是否需要为数组或对象。 From your reducer, initial state is an empty array, but if FETCH_WEATHER is dispatched it returns array and FETCH_WEATHER_ERROR returns object. 从减速器开始,初始状态是一个空数组,但是如果调度了FETCH_WEATHER ,它将返回数组,而FETCH_WEATHER_ERROR将返回object。

I suggest you modify combineReducers as well, there is no point passing same reducer to different properties in root state. 我建议您也修改CombineReducers,在根状态下将相同的reducer传递给不同的属性没有意义。

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

is enough. 足够。 Lets assume your state is an Object, with isVisible and weather properties. 让我们假设您的状态是一个具有isVisibleweather属性的Object。 So your reducer will become. 因此,您的减速器将成为。

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;
 }

And finally if you want to show when isVisible is true you have to 最后,如果您想显示何时isVisible为true,则必须

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

Split code into smaller reducers: 将代码拆分为较小的缩减器:

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 };

Now each reducer function has own zone of control. 现在,每个异径管功能都有自己的控制区。

In your reducer you have mixed type of state. 在减速器中,您有混合状态。 Default is an empty array [] , but later you have returned an object ( {state, isVisible: false} ). 默认值为空数组[] ,但稍后您返回了一个对象( {state, isVisible: false} )。 Don't do that. 不要那样做 You also reduce weather and isVisible nodes of state by the same WeatherReducer . 您还可以通过相同的WeatherReducer减少weatherisVisible状态节点。 It's not correct, because the logic of modifying this nodes is different. 这是不正确的,因为修改此节点的逻辑是不同的。

you need an Action that will change the isVisible eq 您需要一个可更改isVisible eq的操作

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

and

case FETCH_WEATHER_ERROR: 
   return {...state, isVisible: true}

{this.props.isVisible ? null : <Alert /> } {this.props.isVisible ? null : <Alert /> } should be replace by {this.props.isVisible ? <Alert /> : null } {this.props.isVisible ? null : <Alert /> }应该替换为{this.props.isVisible ? <Alert /> : null } {this.props.isVisible ? <Alert /> : null } because when this.props.isVisible is true then only will be visible but you are doing it wrong.. Hoped it helped {this.props.isVisible ? <Alert /> : null }因为当this.props.isVisibletrue时,只有它可见,但您做错了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM