【问题标题】:Warning: Failed propType: Required prop `dimensionName` was not specified in `DimensionPicker`. Check the render method of `Connect(DimensionPicker)`警告:失败的 propType:在 `DimensionPicker` 中未指定必需的 prop `dimensionName`。检查 `Connect(DimensionPicker)` 的渲染方法
【发布时间】:2016-02-19 02:14:18
【问题描述】:

我有以下 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. reducer 将初始化状态
  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

【问题讨论】:

  • 您已经省略了实际初始化 redux 并执行初始 render 的代码。您执行此操作的时间点将决定何时填充初始数据。此外,App 的最佳实践是connected 而不是DimensionPicker。这使得它可以重复使用,尽管它不能解决你的直接问题。
  • 我在上面添加了我的初始渲染代码。请看一下

标签: javascript reactjs redux react-redux


【解决方案1】:

您将“初始状态”作为默认参数提供给减速器,但这仅在实际调用该减速器时用作该减速器的默认状态。由于您尚未调度任何操作,初始状态取决于您提供给createStore 的值,大概在MovieLensAppStore 中。

我不知道您是如何创建商店的,但这应该可以,例如:

createStore(
    combineReducers({
        dimensionPickerReducer
    }),
    {
        dimensionPicker: {
            dimenisionName: '',
            isLoading :'false',
            error : '',
            currentAttribute: '',
            attributeList: []
        }
    }
)

【讨论】:

  • 我添加了这个。但现在它又给出了一个错误(以及以前的错误)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.
  • 看看这里。我发布了问题的根本原因stackoverflow.com/questions/35402389/…
  • 根据您的 GitHub,您似乎发现了我的错误。忘记了商店钥匙。我已编辑我的答案以符合要求。
【解决方案2】:

问题已解决。麻烦的是 combineReducers 没有正确初始化 state,这就是为什么容器控件说 props 没有被指定(因为 state 是空的)。

解决方案记录在这里

combineReducers causes code to break

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    • 2016-03-01
    • 2017-04-07
    相关资源
    最近更新 更多