我有非常简单的代码,我的想法是通过ajax获取一些数据并使它们在应用程序的整个生命周期中都可用。我需要这种方式,因为我在许多地方使用Index组件,而且每次渲染时都无法获取数据。 我通过控制台中的所有消息看到,我需要获取所需的数据并更新store.state,我看到我需要的所有数据,但索引组件永远不会更新,我不会在里面获取这些数据它。 我是新手,所以我可能只是对愚蠢的事情视而不见...... 我也很欣赏有关我的问题的整个架构的任何建议。
var React = require('react');
var ReactDOM = require('react-dom');
var Router = require('react-router').Router;
var Route = require('react-router').Route;
var createBrowserHistory = require('history/lib/createBrowserHistory');
var createStore = require('redux').createStore;
var Provider = require('react-redux').Provider;
var connect = require('react-redux').connect;
window.onload=setOptions;
var options = [];
var setOptReducer = function (state = [], action) {
console.log('setOptReducer was called with state', state, 'and action', action)
switch (action.type) {
case 'ADD_ITEM':
return [
...state,
action.data
]
default:
return state;
}
};
var setOptCreator = function (options) {
console.log("options inside setOptCreator ", options);
return {
type: 'ADD_ITEM',
data: options
}
};
var optDispatcher = function(options) {
store.dispatch(setOptCreator(options));
};
const store = createStore(setOptReducer, options);
function setOptions() {
loadFromServer(optDispatcher);
};
function mapStateToProps(state) {
console.log("mapStateToProps ",state);
return {options: state.options};
};
var IndexContainer = React.createClass({
render: function () {
return (
<div>
{console.log("Index rendered with options ", this.props.options)}
</div>
);
}
});
function loadFromServer(callback) {
function option(value, label) {
this.value = value;
this.label = label;
}
$.ajax({
url: "/api/",
dataType: 'json',
cache: false,
success: function (data) {
var options = [];
{.....put some elements from data to options}
console.log("options inside loadFromServer is ", options);
callback(options);
console.log('store state after callback:', store.getState());
}.bind(this)
});
};
var Index = connect(mapStateToProps)(IndexContainer);
ReactDOM.render(
<Provider store={store}>
<Router history={createBrowserHistory()}>
<Route path="/" component={Index}/>
</Router>
</Provider>,
document.getElementById("container")
);
答案 0 :(得分:4)
基本上在mapStateToProps中,你有options: state.options;
但是现在没有名为的东西作为状态中的选项。在文档http://redux.js.org/docs/api/createStore.html中,当您使用createStore
作为参数传递setOptReducer
时,它会创建一个只包含一个reducer的商店,因此state
就可以了拥有是商店的价值。
您可以尝试将mapStateToProps
更改为此内容吗?
function mapStateToProps(state) {
console.log("mapStateToProps ",state);
return {options: state};
};
如果这样可行,那么你可以重命名一些东西,因为现在它可能会令人困惑。例如,删除var options = []
并将reducer函数更改为options并具有
const store = createStore(options, []);
建议使用combineReducers
从多个中创建单个根reducer - 如果将其传递给createStore
,则状态为对象,然后您可以执行{{1 }}
希望它不会太混乱
答案 1 :(得分:3)
最后在luanped的巨大帮助下,我找到了问题的根源,我相信值得作为一个单独的答案。
mapStateToProps
实际上无法将state.options
映射到options
,因为state
不包含options
属性,因为在setOptReducer
中通过将actionData
数组连接到state
数组来保存state
,而不是将其作为对象 case 'ADD_ITEM':
return [
...state,
action.data
]
的单独命名属性:
mapStateToProps
所以options
并没有真正改变undefined
(将undefined
更改为state
)以及该组件没有改变的原因重新渲染。
因此,决定将整个options
公开为state
,这正在改变组件的this.props,因此它可以工作。
为了使其工作更正确,不将整个options
暴露给组件,而只暴露 return {
...state,
options: action.data
}
部分,reducer的代码应该是:
state
这种方式options
变为mapStateToProps
属性,// article.php
public function my_complex_query()
{
// code here. Eloquent, or Query Builder or
// Raw SQL
return $result;
}
看到它并且组件重新渲染。