代码之家  ›  专栏  ›  技术社区  ›  Ebbs

React Redux组件未在商店中显示新的道具

  •  0
  • Ebbs  · 技术社区  · 6 年前

    我正在尝试使用react(在本例中也是bootstrap v4)创建自己的警报组件。基本上,如果发生了需要通知用户的事情,请创建一条消息,将其放入存储区,并让react呈现警报。我知道我所做的应该是可能的,但是我是新来的,足以做出反应,我遗漏了一些东西/不理解反应是如何工作的,这导致没有显示警报。

    首先,我警告所有其他组件都可用,因此我将其放入 app.js :

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { Provider } from 'react-redux';
    import { PersistGate } from 'redux-persist/integration/react';
    import AppRouter from './routers/AppRouter';
    import configureStore from './store/configureStore';
    
    import Alerts from './components/controls/Alerts';
    
    const { store, persistor } = configureStore();
    
    const jsx = (
        <Provider store={store}>
            <PersistGate loading={null} persistor={persistor}>
                <Alerts />
                <AppRouter />
            </PersistGate>
        </Provider>
    );
    
    ReactDOM.render(jsx, document.getElementById('root'));
    

    接下来是的组件 Alerts . 首先是行动:

    // DISPLAY_ALERT
    export const displayAlert = (message, severity) => ({
        type: 'DISPLAY_ALERT',
        message: message,
        severity: severity
    });
    
    // DISMISS_ALERT
    export const dismissAlert = (id) => ({
        type: 'DISMISS_ALERT',
        id: id
    });
    

    减速器:

    const alertsDefaultState = [];
    
    const alertNotify = (state, action) => {
        let queue = state;
    
        if (!queue || !Array.isArray(queue))
            queue = [];
    
        let newAlert = {
            id: getUniqueId(),
            message: action.message,
            severity: action.severity
        };
    
        queue.push(newAlert);
    
        return queue;
    };
    
    const alertDismiss = (state, action) => {
        const newQueue = state.filter((element) => element.id !== action.id);
    
        return newQueue;
    };
    
    const getUniqueId = () => {
        return (Date.now().toString(36) + Math.random().toString(36).substr(2, 5)).toUpperCase();
    };
    
    export default (state = alertsDefaultState, action) => {
        switch (action.type) {
            case 'DISPLAY_ALERT':
                return alertNotify(state, action);
            case 'DISMISS_ALERT':
                return alertDismiss(state, action);
            case 'LOG_OUT_OF_API':
                return [];
            default:
                return state;
        }
    };
    

    商店:

    import { createStore, combineReducers } from 'redux';
    import { persistStore, persistReducer } from 'redux-persist';
    import storage from 'redux-persist/lib/storage';
    import alertsReducer from '../reducers/alerts';
    
    export default () => {
        const persistConfig = {
            key: 'root',
            storage,
        };
    
        let reducers = combineReducers({
            // Other reducers
            alerts: alertsReducer
        });
    
        let store = createStore(
            persistReducer(persistConfig, reducers),
            window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
        );
    
        let persistor = persistStore(store);
    
        return { store, persistor };
    };
    

    最后是 警报 组件:

    import React from 'react';
    import { connect } from 'react-redux';
    import { dismissAlert } from '../../actions/alerts';
    
    class Alerts extends React.Component {
        constructor(props) {
            super(props);
        }
    
        getAlerts = () => {
            if (!this.props.alerts || this.props.alerts.length === 0)
                return null;
    
            const alertFixed = {
                position:'fixed',
                top: '0px',
                left: '0px',
                width: '100%',
                zIndex: 9999,
                borderRadius: '0px'
            };
    
            return (
                <div style={alertFixed}>
                    {
                        this.props.alerts.map((alert) => {
                            const alertClass = `alert alert-${alert.severity} alert-dismissible m-4`
                            setTimeout(() => {
                                this.props.dispatch(dismissAlert(alert.id));
                            }, 5000);
                            return (
                                <div key={alert.id} id={alert.id} className={alertClass} role="alert">
                                    <button type="button" className="close" data-dismiss="alert" aria-label="Close">
                                        <span aria-hidden="true">&times;</span>
                                    </button>
                                    { alert.message }
                                </div>
                                );
                            }
                        )
                    }
                </div>
            );
        }
    
        render() {
            return this.getAlerts()
        }
    }
    
    const mapStateToProps = (state) => {
        return {
            alerts: state.alerts
        }
    };
    
    export default connect(mapStateToProps)(Alerts);
    

    最后一件事是,我有一个针对警报类型的const类:

    export default {
        Info: 'info',
        Success: 'success',
        Warning: 'warning',
        Error: 'danger',
    };
    

    如果我运行上述代码并在 alerts store ,然后渲染。但是,如果我在事件中向存储中添加一些内容,例如单击按钮,我可以看到正在将警报添加到存储中,但组件不会将其添加到DOM中。

    我错过了什么?

    编辑:

    Here is a code sandbox

    1 回复  |  直到 6 年前
        1
  •  1
  •   Alwaysblue    6 年前

    数组是javascript中的引用类型

    在你

    const alertNotify = (state, action) => {
        let queue = state;
    
        if (!queue || !Array.isArray(queue))
            queue = [];
    
        let newAlert = {
            id: getUniqueId(),
            message: action.message,
            severity: action.severity
        };
    
        queue.push(newAlert);
    
        return queue;
    };
    

    而不是这样做

     let queue = state;
    

    你需要做一个 复印件 (而不是引用它)然后执行

    queue.push(newAlert);
    

    例如,将初始队列声明更改为该声明(我正在使用spread operator复制您的已传递状态,然后在队列中推送newalert

    let queue = [...state];
    

    因为你回来的时候排队, 里面没有状态

    这种情况正在被解雇

     if (!this.props.alerts || this.props.alerts.length === 0)