我正试图将我的初始状态变成一个组件,但我似乎无法到达那里。我正在设置我的初始状态以获得名为topic_drpDwn
的道具,但在MonitoringPage
组件中,我看不到该状态出现。
我的index.js看起来像这样:
import 'babel-polyfill';
import React from 'react';
import { render } from 'react-dom';
import { Router, browserHistory } from 'react-router';
import routes from './routes';
import {Provider} from 'react-redux';
import './styles/styles.css'; //Webpack can import CSS files
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import configureStore from './store/configureStore';
import * as ReactBootstrap from 'react-bootstrap';
let initialState = {
topic_drpDwn: ["nifi", "drop 2", "tsys"]
};
const store = configureStore(initialState);
render (
<Provider store={store}>
<Router history={browserHistory} routes={routes} />
</Provider>,
document.getElementById('app')
);
我的MonitoringPage.js看起来像这样(这是我期待的this.props.topic_drpDwn
)
import React, {PropTypes} from 'react';
import {connect} from 'react-redux';
import * as monitoringActions from '../../actions/monitoringActions';
import * as ReactBootstrap from 'react-bootstrap';
class MonitoringPage extends React.Component {
constructor (props, context) {
super(props, context);
this.state = {
drplist: {drpTitle: "Sample topic selector",
drpVal: ["tysys", "kafka-jmx", "nifi"]
}
};
this.onDropChange = this.onDropChange.bind(this);
}
onDropChange (event) {
let drplist = Object.assign({}, this.state.drplist);
console.log("drop changed")
drplist.drpTitle = event;
this.setState({drplist: drplist});
}
mkList (x) {
return <ReactBootstrap.MenuItem eventKey={x}>{x}</ReactBootstrap.MenuItem>
}
render (title) {
let data = [1,2,3,4]
console.log("data", title)
console.log("state: ", this.state)
return (
<div>
<h1>Monitoring</h1>
<h2>Monitoring Page under dev, example save button</h2>
<input
type="text"
/>
<input
type="submit"
value="save" />
<ReactBootstrap.DropdownButton title={this.state.drplist.drpTitle} id="bg-vertical-1" onSelect={this.onDropChange}>
{this.state.drplist.drpVal.map(this.mkList)}
</ReactBootstrap.DropdownButton>
</div>
);
}
}
function mapStateToProps(state, ownProps) {
console.log("initial state indx: ", JSON.stringify(state));
return {
monitoring: state.monitoring,
topic_drpDwn: state.topic_drpDwn
};
}
export default connect(mapStateToProps) (MonitoringPage);
并配置商店如下所示:
export default function configureStore(initialState) {
console.log("initial state: ", initialState)
initialState = initialState || { topic_drpDwn: [] }
console.log("initial state2: ", initialState)
return finalCreateStore(
rootReducer,
initialState
);
}
这里的 console.log
确实打印了index.js
作为初始状态的内容,但如果我在this.props
组件内部记录MonitoringPage
,我就不会看到初始状态显示......
console.log("props:", this.props)
{
"children": null,
"history": {},
"location": {
"$searchBase": {
"search": "",
"searchBase": ""
},
"action": "POP",
"hash": "",
"key": "9cjw6a",
"pathname": "/monitoring",
"query": {},
"search": "",
"state": null
},
"monitoring": [],
"params": {},
"route": {
"path": "monitoring"
},
"routeParams": {},
"routes": [
{
"childRoutes": [
{
"path": "onboarding"
},
{
"path": "topicregistry"
},
{
"path": "monitoring"
},
{
"path": "about"
}
],
"indexRoute": {},
"path": "/"
},
{
"path": "monitoring"
}
]
}
我正在尝试按照本指南关于如何在减速器之外设置初始状态。
https://egghead.io/lessons/javascript-redux-supplying-the-initial-state
----- EDIT --------
我在构造函数中取出了上下文,然后立即记录了道具并将其取回:
{
"children": null,
"history": {},
"location": {
"$searchBase": {
"search": "",
"searchBase": ""
},
"action": "POP",
"hash": "",
"key": "9cjw6a",
"pathname": "/monitoring",
"query": {},
"search": "",
"state": null
},
"monitoring": [],
"params": {},
"route": {
"path": "monitoring"
},
"routeParams": {},
"routes": [
{
"childRoutes": [
{
"path": "onboarding"
},
{
"path": "topicregistry"
},
{
"path": "monitoring"
},
{
"path": "about"
}
],
"indexRoute": {},
"path": "/"
},
{
"path": "monitoring"
}
]
}
另外,我的monitoringReducer看起来像这样:
export default function monitoringReducer (state = [], action) {
switch(action.type) {
case 'TOPIC_SELECT':
return Object.assign({}, state, topic_selected: [action.topic]);
default:
return state;
}
}
我的rootReducer看起来像这样:
import {combineReducers} from 'redux';
import monitoring from './monitoringReducer';
const rootReducer = combineReducers({
monitoring
});
export default rootReducer;
答案 0 :(得分:2)
topic_drpDwn的缩减器是什么?现在只有一个监控减速器,因此所有州都处于状态监控状态。 state.topic_drpDwn没有reducer。所以redux说state.topic_drpDwn没有减速器。
答案 1 :(得分:0)
createStore(reducer, [preloadedState], [enhancer])
我们关注的是第二个参数preloadedState
。
从Redux引用createStore
docs。
[
preloadedState
](任意):初始状态。您可以选择将其指定为在通用应用程序中从服务器中保持状态,或者还原以前序列化的用户会话。如果您使用combineReducers
生成reducer
,则必须是明文 与传递给它的键相同的形状的对象。否则,你 可以自由地传递减速器可以理解的任何东西。
如果您正在使用combineReducers
并且还将一个initialState(或preloadedState)传递给createStore
,请确保密钥完全相同(不是更多,不是更少)。
如果违反此规定,您可能会在控制台中看到警告:
Unexpected key "topic_drpDwn" found in initialState argument passed to createStore. Expected to find one of the known reducer keys instead: "monitoring". Unexpected keys will be ignored.
<强>解决方案:强>
使用单个reducer管理所有内容并将其传递给createStore
。
finalCreateStore(reducer, initialState);
reducer
管理外包。在您的情况下,状态键monitoring
和topic_drpDwn
都由同一个reducer处理。
但当然,这不是我们想要的任何App,因为我们需要有抽象的状态切片。因此,让我们分割并创建多个reducers来管理特定的状态切片。因此,您需要为topic_drpDwn
和monitoring
设置单独的缩减器。然后使用combineReducers
创建rootReducer
并将其传递给createStore
。
答案 2 :(得分:-1)
您应该使用react组件生命周期,并在componentWillMount()步骤调用操作中设置初始状态。
但更好的方法是 - 将reducer函数中的初始状态设置为默认参数:
const initialState = {
someValue: {},
};
export default function someReducer(state = initialState, action) {
switch (action.type) {
case SOME_ACTION_TYPE:
return { ...state, someValue: action.payload };
}
}