redux - состояние редуктора пустое

Я пытаюсь воспроизвести что-то похожее на пример TodoList в основном примере документов. Второй редьюсер получает массив — styleItems = [{... ... }, {... ...}] — и затем вызывает первую функцию, чтобы воздействовать на каждый из отдельных объектов.

Я предоставляю initialState контейнеру приложения с помощью следующего, как показано в containers/app.js. Однако состояние, передаваемое редюсеру styleItems, кажется пустым массивом — каждый раз.

Однако react отображает пользовательский интерфейс на основе исходной конфигурации, а react dev-tools показывает структуру состояния, как и ожидалось. Магазин избыточности каким-то образом видит то же самое, что и реакция?

контейнеры/app.js

function starterInfo(state) {
    return {

        // The ID of this particular object
        id: 12345,

        // Various keys and theri css values
        styleItems: [
            {
                pk: 31,
                order: 1,
                label: 'Caption text color',
                css_identifier: '.caption-text',
                css_attribute: 'color',
                css_value: '#FFFFFF'
            },
            {
                pk:23,
                order: 2,
                label: 'Caption link color',
                css_identifier: '.caption-link',
                css_attribute: 'color',
                css_value: '#FEFEFE'
            }
        ],

        // Network state info
        currently_fetching: false,
        currently_posting: false
    }
}

export default connect(starterInfo)(App)

редьюсеры/index.js

// This handles a single styleItem object within the array
function change_css(state = {}, action){
    switch (action.type){
        case actions.CHANGE_CSS:

            if (state.order !== action.order){
                return state
            }

            return {
                ...state,
                css_value
            }

        default:
            return state
    }
}

// This handles the styles array in the global state
function styleItems(state = [], action){
    switch(action.type){       
        case actions.CHANGE_CSS:

            const foobar = state.map(styleItem =>
                change_css(styleItem, action)
                )            

            return foobar

        default:
            return state
    }
}

person snakesNbronies    schedule 18.01.2016    source источник


Ответы (2)


Короткий ответ заключается в том, что вы не совсем правильно передаете начальное состояние. Первый аргумент функции connect для привязок React Redux — mapStateToProps. Цель этой функции — взять состояние, которое уже существует в вашем приложении, и сопоставить его со свойствами вашего компонента. То, что вы делаете в своей функции starterInfo, просто жестко кодирует состояние вашего компонента. Поскольку вы возвращаете простой объект, React на самом деле не знает разницы, поэтому работает нормально, но Redux еще не знает о состоянии вашего приложения.

Вместо этого вы должны предоставить свое начальное состояние непосредственно редукторам, например:

const intialStyleItemsState = [
    {
        pk: 31,
        order: 1,
        label: 'Caption text color',
        css_identifier: '.caption-text',
        css_attribute: 'color',
        css_value: '#FFFFFF'
    },
    {
        pk:23,
        order: 2,
        label: 'Caption link color',
        css_identifier: '.caption-link',
        css_attribute: 'color',
        css_value: '#FEFEFE'
    }
];

function styleItems(state = intialStyleItemsState, action){ ...

И в конце концов, поскольку вы разделяете свои редукторы, вам нужно будет снова объединить их вместе с помощью утилиты Redux combineReducers, предоставить этот корневой редуктор в свой магазин и идти оттуда.

person Nick Ball    schedule 18.01.2016

Вы также можете передать начальное состояние с помощью функции createstore редукции, которая принимает в качестве аргумента createStore(reducer, [initialState]) http://rackt.org/redux/docs/api/createStore.html

Допустим, у вас есть два редуктора.

change_css(state = {}, action)
function styleItems(state = [], action)

Если вы используете comibneReducer для инициализации своего состояния

var reducer = combineReducers({
    css: change_css,
    items: styleItems
})

Теперь

var store = createStore(reducer)
console.log(store.getState())

В вашем магазине будет { css: {}, items: [] }

Теперь, если вы хотите инициализировать состояние, вы можете передать начальное состояние в качестве второго аргумента функции createStore.

createStore(reducer, {css:{some properties},items:[{name:"obj1"},{name:"obj2"},{name:"obj3"}]})

Теперь ваше хранилище будет содержать начальное состояние. {css:{some properties,items:[{name:"obj1"},{name:"obj2"},{name:"obj3"}]}

Например, вы можете передать это состояние с сервера и установить его в качестве начального состояния вашего приложения.

person Aaleks    schedule 19.01.2016