我有以下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') )
我的期望是
但这不会发生。相反,我得到一个警告像
Warning: Failed propType: Required prop `dimensionName` was not specified in `DimensionPicker`. Check the render method of `Connect(DimensionPicker)`.
我已经在这里发布了我的整个代码库
https://github.com/abhitechdojo/MovieLensReact
问题已解决。这里麻烦的是,CombineReducers没有正确初始化状态,这就是为什么容器控件说未指定props的原因(因为状态为空)。