Предупреждение: ошибка propType: необходимая опора `dimensionName` не была указана в `DimensionPicker`. Проверьте метод рендеринга Connect (DimensionPicker)

У меня есть следующий компонент Redux+React

import {PropTypes, React, Component} from 'react';
import Select from 'react-select';

class DimensionPicker extends Component {
    componentDidMount() {
        const {onLoad} = this.props;
        onLoad();
    }
    render() {
        const {onChange, attributeList, currentAttribute} = this.props;
        return (
            <div>
                <Select value={currentAttribute} options={attributeList} onChange={onChange} />
            </div>
        )       
    }
}

DimensionPicker.propTypes = {
    dimensionName: PropTypes.string.isRequired,
    onChange: PropTypes.func.isRequired,
    attributeList: PropTypes.arrayOf(PropTypes.shape({
        value: PropTypes.string.isRequired,
        label: PropTypes.string.isRequired
    }).isRequired).isRequired,
    currentAttribute: PropTypes.string.isRequired
}

export default DimensionPicker;

и следующий компонент контейнера

import React from 'react';
import DimensionPickerActions from '../actions/DimensionPickerActions';
import {connect} from 'react-redux';
import DimensionPicker from './controls/DimensionPicker.jsx';

const mapStateToProps = (state) => {
    return {
        dimensionName: state.dimensionName,
        attributeList: state.attributeList,
        currentAttribute: state.currentAttribute
    }
}

const mapDispatchToProps = (state) => {
    return {
        onChange: (newValue) => {
            dispatch(updateAttributeSelection(newValue));
        },
        onLoad: () => {
            dispatch(fetchDimensionAttributes(state.dimensionName));
        }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(DimensionPicker);

У меня также есть редуктор, который заполняет начальное состояние

// define the state tree for the dimenion picker.
const initialState = {
    dimenisionName: '',
    isLoading :'false',
    error : '',
    currentAttribute: '',
    attributeList: []
}

function dimensionPickerReducer(state = initialState, action) {

    switch(action.type) {
        case ATTRIBUTE_SELECTION_CHANGED: 
            return Object.assign({}, state, {currentAttribute: action.data});
            break;
        case REQUEST_DIMENSION_ATTRIBUTES:
            return Object.assign({}, state, {isLoading: 'true', error: ''})
            break;
        case DIMENSION_ATTRIBUTES_RECEIVED:
            return Object.assign({}, state, {attributeList: action.data, isLoading: 'false', error: action.error});
            break;
        case SET_DIMENSION_NAME:
            return Object.assign({}, state, {dimensionName: action.data})
            break;
        default:
            return state;
            break;
    }
}

export default dimensionPickerReducer;

Я строю свой государственный магазин вот так

import React from 'react';
import { createStore, combineReducers, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import DataTableReducer from './reducers/DataTableReducer';
import DimensionPickerReducer from './reducers/DimensionPickerReducer';

const combinedReducer = combineReducers({
    dataTable: DataTableReducer,
    dimensionPicker: DimensionPickerReducer
});
export default applyMiddleware(thunk)(createStore)(combinedReducer);

Я загружаю компонент как

import React from 'react';
import DimensionPicker from '../containers/DimensionPickerContainer';

const App = () => (
    <div>
    <DimensionPicker dimensionName="Genre"/>
    </div>
    )

export default App;

и, наконец, вот как я загружаю свое приложение

import React from 'react';
import {render} from 'react-dom';
import {Provider} from 'react-redux';
import App from './Reports/App.jsx';
import MovieLensAppStore from './stores/MovieLensAppStore';

render (
    <Provider store={MovieLensAppStore}>
        <App />
    </Provider>,
    document.getElementById('container')
    )

Я ожидал, что

  1. редуктор инициализирует состояние
  2. компонент контейнера сопоставит это состояние с реквизитами, используя 2 метода в компоненте контейнера.
  3. наконец, когда компонент загружается, он будет иметь доступное состояние и методы отправки.

но этого не происходит. вместо этого я получаю предупреждение вроде

Warning: Failed propType: Required prop `dimensionName` was not specified in `DimensionPicker`. Check the render method of `Connect(DimensionPicker)`.

Я опубликовал всю свою кодовую базу здесь

https://github.com/abhitechdojo/MovieLensReact


person Knows Not Much    schedule 13.02.2016    source источник
comment
Вы пропустили код, который фактически инициализирует избыточность и выполняет начальное render. Точка, в которой вы это сделаете, определит, когда будут заполнены исходные данные. Кроме того, рекомендуется, чтобы приложение было connected, а не DimensionPicker. Это делает его пригодным для повторного использования, хотя это не решит вашу непосредственную проблему.   -  person EugeneZ    schedule 13.02.2016
comment
Я добавил свой исходный код рендеринга выше. Пожалуйста, посмотрите   -  person Knows Not Much    schedule 13.02.2016


Ответы (2)


Вы предоставляете «начальное состояние» в качестве параметра по умолчанию для вашего редуктора, но оно используется только как состояние по умолчанию для этого редуктора, когда он фактически вызывается. Поскольку вы еще не отправили никаких действий, начальное состояние зависит от значения, которое вы предоставили createStore, предположительно в MovieLensAppStore.

Я не знаю, как вы создаете свой магазин, но это должно работать, например:

createStore(
    combineReducers({
        dimensionPickerReducer
    }),
    {
        dimensionPicker: {
            dimenisionName: '',
            isLoading :'false',
            error : '',
            currentAttribute: '',
            attributeList: []
        }
    }
)
person EugeneZ    schedule 13.02.2016
comment
Я добавил это. но теперь выдает еще одну ошибку (вместе с предыдущими) Unexpected keys "dimenisionName", "isLoading", "error", "currentAttribute", "attributeList" found in initialState argument passed to createStore. Expected to find one of the known reducer keys instead: "dataTable", "dimensionPicker". Unexpected keys will be ignored. - person Knows Not Much; 13.02.2016
comment
Посмотрите здесь. Я опубликовал основную причину проблемы stackoverflow.com/questions /35402389/ - person Knows Not Much; 15.02.2016
comment
Основываясь на вашем GitHub, похоже, вы поняли мою ошибку. Забыл ключ от магазина. Я отредактировал свой ответ, чтобы соответствовать. - person EugeneZ; 18.02.2016

Проблема была решена. проблема здесь в том, что combReducers не инициализирует состояние должным образом, и поэтому элемент управления контейнером говорит, что свойства не были указаны (поскольку состояние пусто).

Решение описано здесь

combineReducers вызывает сбой кода

person Knows Not Much    schedule 18.02.2016