本文介绍了Dispatch(action) 改变了 store 状态但组件没有更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有非常简单的代码,想法是通过 ajax 获取一些数据并使它们在应用程序的整个生命周期中可用.我需要这种方式,因为我在很多地方都使用了 Index 组件,而且每次渲染时我都无法获取数据.我通过控制台中的所有消息看到,获取了我需要的数据并更新了 store.state,我在那里看到了我需要的所有数据,但 Index 组件从未更新,而且我没有在其中获取这些数据.我是新手,所以可能我只是对一些愚蠢的事情视而不见......对于我的问题的整个架构的任何建议,我也将不胜感激.
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 选项 = [];var setOptReducer = 函数(状态 = [],动作){console.log('setOptReducer 被调用状态', state, 'and action', action)开关(动作.类型){案例ADD_ITEM":返回 [...状态,动作数据]默认:返回状态;}};var setOptCreator = 函数(选项){console.log("setOptCreator 中的选项", options);返回 {类型:'ADD_ITEM',数据:选项}};var optDispatcher = 函数(选项){store.dispatch(setOptCreator(options));};const store = createStore(setOptReducer, options);函数 setOptions() {loadFromServer(optDispatcher);};函数 mapStateToProps(state) {console.log("mapStateToProps ",state);返回 {options: state.options};};var IndexContainer = React.createClass({渲染:函数(){返回 (<div>{console.log("使用选项渲染的索引", this.props.options)}
);}});函数 loadFromServer(回调){功能选项(值,标签){this.value = 值;this.label = 标签;}$.ajax({url: "/api/",数据类型:'json',缓存:假,成功:功能(数据){var 选项 = [];{..... 将一些元素从数据放入选项}console.log("loadFromServer 里面的选项是", options);回调(选项);console.log('回调后存储状态:', store.getState());}.绑定(这个)});};var Index = connect(mapStateToProps)(IndexContainer);ReactDOM.render(<提供者商店={商店}><路由器历史={createBrowserHistory()}><Route path="/" component={Index}/></路由器></提供者>,document.getElementById("容器"));
解决方案
基本上在你的 mapStateToProps 中,你有 options: state.options;
但现在没有东西 named 作为选项中的状态.来自文档 http://redux.js.org/docs/api/createStore.html,当你使用 createStore
传入 setOptReducer
作为参数时,它会创建一个只有一个 reducer 的 store,结果 state
own 是商店的价值.
您可以尝试将您的 mapStateToProps
更改为这个吗?
function mapStateToProps(state) {console.log("mapStateToProps ",state);返回{选项:状态};};
如果这可行,那么您可以重命名一些内容,因为现在它可能会令人困惑.例如删除 var options = []
并将 reducer 函数更改为 options 并具有
const store = createStore(options, []);
建议使用 combineReducers
从多个中创建单个 root reducer - 如果您将其传递给 createStore
,则状态是一个对象,并且您然后可以做 state.setOptReducer
希望不要太混乱
I have pretty simple code, the idea is to fetch some data via ajax and make them available for the whole life of app. I need it this way because I use the Index component in many places, and I cannot afford fetch the data each time I render it.I see via all that messages in console, that the data I need is fetched and the store.state is updated and I see there all data I need, but Index component is never updated, and I don't get this data inside it.I am a novice, so probably I'm just blind to something stupid...I'd also appreciate any piece of advise regarding the whole architecture for my problem.
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")
);
解决方案
Basically in your mapStateToProps, you have options: state.options;
but right now there is no thing named as options in the state. From the docs http://redux.js.org/docs/api/createStore.html, when you use createStore
passing in setOptReducer
as argument, it creates a store with just one reducer and as a result state
on it's own is the value of the store.
Could you try changing your mapStateToProps
to this?
function mapStateToProps(state) {
console.log("mapStateToProps ",state);
return {options: state};
};
If this works, then you could rename some things, since right now it might be confusing. For example removing var options = []
and change the reducer function to options and have
const store = createStore(options, []);
It is recommended to use combineReducers
to create a single root reducer out of many - and if you pass that to createStore
, then the state is an object, and you can then do state.setOptReducer
Hope it's not too confusing
这篇关于Dispatch(action) 改变了 store 状态但组件没有更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!