尝试使用React + Redux,并且可能做起来显然很愚蠢,因为在获取数据时,触发操作以通过网络获取数据的组件不会得到更新(重新呈现)。
这是我的代码的相关位:
顶级index.js充当应用程序的入口点:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { Router, browserHistory } from 'react-router';
import reduxPromise from 'redux-promise';
import createLogger from 'redux-logger';
const logger = createLogger();
import routes from './routes';
import reducers from './reducers';
const createStoreWithMiddleware = applyMiddleware(reduxPromise, logger)(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<Router history={browserHistory} routes={routes} />
</Provider>
, document.querySelector('.container'));
顶级容器应用程序:
import React, {Component} from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as Actions from '../actions';
import Header from '../components/header';
import Showcase from '../components/showcase';
function mapStateToProps(state) {
return {
resources: state.resources
}
}
function mapDispatchToProps(dispatch) {
return {
fetchResources: () => {
dispatch(Actions.fetchResources());
}
}
}
class App extends Component {
render() {
console.log('props in App', this.props);
return (
<div>
<Header/>
<Showcase
fetchResources={this.props.fetchResources}
resources={this.props.resources}
/>
</div>
);
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App)
组件将在要挂载并触发其显示获取的数据时触发操作以发送数据请求:
import React, {Component} from 'react';
import {connect} from 'react-redux';
class Showcase extends Component {
constructor(props) {
super(props);
}
componentWillMount() {
this.props.fetchResources();
}
render() {
console.log('resources', this.props);
return (
<div>
This is showcase
</div>
);
}
}
export default connect(state => ({resources: state.resources}))(Showcase)
动作创建者:
import * as types from '../constants/ActionTypes';
import axios from 'axios';
export function fetchResources() {
return {
type: types.FETCH_FIRST,
payload: axios.get('/sampledata/1.json')
}
}
减速器的提取操作:
import * as types from '../constants/ActionTypes';
export default function resourcesReducer (state={}, action) {
switch (action.type) {
case types.FETCH_FIRST:
console.log('about to return', Object.assign (state, {resources: action.payload.data }))
return Object.assign (state, {resources: action.payload.data });
default:
return state
}
};
最后是根减速器:
import { combineReducers } from 'redux';
import navigationReducer from './navigation-reducer';
import resourcesReducer from './resources-reducer';
const rootReducer = combineReducers({
navigationReducer,
resourcesReducer
});
export default rootReducer;
因此,这就是我正在观察的内容。请求数据的操作已成功触发,发送了请求,resolver在promise解析后收到请求,并使用获取的数据更新状态。在这一点上,我希望顶级App
组件和该Showcase
组件能够检测到商店已更新并重新呈现,但是在控制台中看不到它。
另外,我redux-logger
对的控制台输出感到困惑:
Specifically, I am surprized to see that the state
contains reducers from the rootReducer — I don't know if it's right (an example on Redux logger Github page shows a state without reducers). It also seems surprising that the prev state
as reported by redux-logger
contains the same resourcesReducer
object as the next state
, although intuitively I would expect prev state
to be more or less empty.
Could you please point out what I am doing wrong and how to get React components respond to the state
changes?
==================================================
UPDATED:
1) Changed the mapStateToProps
function in the App
component so that it correctly maps to reducer states:
function mapStateToProps(state) {
return {
resources: state.resourcesReducer
}
}
2) Still passing the resources
down to the `Showcase component:
render() {
console.log('props in App', this.props);
return (
<div>
<Header navigateActions={this.props.navigateActions}/>
React simple starter
<Showcase
fetchResources={this.props.fetchResources}
resources={this.props.resources}
/>
</div>
);
3) Trying to display resources
on the screen by stringifying it to see what’s actually inside this object:
render() {
console.log('resources', this.props);
return (
<div>
This is showcase {JSON.stringify(this.props.resources)}
</div>
);
}
See this on the screen: This is showcase {}
. The component does not seem to re-render.
Here’s the screenshot of the console showing that App’s props have updated with the values from the next state
. Still, that did not cause the component to re-render:
UPDATED AGAIN: And my javascript-fu was poor, too. I did not quite realize that by returning Object.assign (state, {resources: action.payload.data });
I was in fact mutating the state, and that a simple inversion of arguments would let me achieve what I intended. Thanks to this discussion on SO for enlightenment.
I am surprized to see that the state contains reducers from the rootReducer
This is how it works. Take a closer look at combineReducers()
.
const rootReducer = combineReducers({
navigationReducer,
resourcesReducer
});
认识到它不是参数列表;它是单个对象参数。也许用冗长的语法更清楚:
var rootReducer = combineReducers({
navigationReducer: navigationReducer,
resourcesReducer: resourcesReducer
});
在resourcesReducer
对国家关键点返回由resourcesReducer()
函数。也就是说,内的state
变量resourcesReducer()
只是整个状态的一部分。
传递的函数connect()
将整个状态作为参数。您的实际外观应该是这样的:
export default connect(state => ({
resources: state.resourcesReducer.resources
}))(Showcase);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句