下面的代码可以工作,但不会在redux调度调用成功时重新驱动应用程序render()。我看不出有什么不对。我在这里放入了模拟数据,以简化调试这个基本问题的过程。
哪些是有效的方式:
- app react组件第一次渲染
- 调度程序成功调用reducer
- 使用正确的状态变化数据成功调用mapStateToProps()
失败:
- 应用程序的重新渲染不会在成功的调度/减速器状态改变时被调用
index.js
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import ReactDOM from 'react-dom';
import './css/index.css';
import App from './containers/App';
import reducer from './reducers';
const store = createStore(
reducer,
{schooldata: {}}
)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
store.dispatch({type: "LOAD_SCHOOL_DATA"});
容器/App.js
import React from 'react';
import { connect, Provider } from 'react-redux';
import {
Route,
NavLink,
BrowserRouter as Router,
Switch,
} from 'react-router-dom';
import Home from "../components/Home";
import Photos from "../components/Photos";
import Attendees from "../components/Attendees";
class App extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
};
render() {
console.log("App is rendering...");
console.log("Props in app: %s", JSON.stringify(this.props));
const src=`${this.props.images}/pic.jpg`;
console.log("src: %s", src);
return (
<div>
<Router>
<div>
<ul>
<li>
<NavLink exact activeClassName="active" to="/">
Home
</NavLink>
</li>
<li>
<NavLink activeClassName="active" to="/photos">
Photos
</NavLink>
</li>
<li>
<NavLink activeClassName="active" to="/attendees">
Attendees
</NavLink>
</li>
</ul>
<hr />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/photos" component={Photos} />
<Route path="/attendees" component={Attendees} />
</Switch>
</div>
</Router>
</div>
)
}
}
const mapStateToProps = (state) => {
console.log("Mapping this: %s", JSON.stringify(state));
return (state.schooldata);
}
const mapDispatchToProps = function (dispatch) {
console.log("Mapping dispatch to props");
return({});
}
export default connect(mapStateToProps)(App);
异径接头/index.js
import axios from 'axios';
import { combineReducers } from 'redux';
import { LOAD_SCHOOL_DATA, ADD_PHOTO, ADD_ATTENDEE } from '../constants/ActionTypes';
const routeAction = (state, action) => {
console.log("routeAction: %s", JSON.stringify(action));
switch(action.type) {
case LOAD_SCHOOL_DATA:
console.log("Action type match.");
return ({
schooldata: {images:"blah", photos:"bleep"},
});
case ADD_PHOTO:
return addPhoto(state);
case ADD_ATTENDEE:
return addAttendee(state);
default:
return {};
}
}
const loadSchoolData = async () => {
await axios.get("/schooldata").then((response) => {
console.log("School data from server: %s", JSON.stringify(response.data));
return(response.data);
})
}
const addPhoto = (state) => {
return state.loadSchoolData.photoList
}
const addAttendee = (state) => {
}
export default combineReducers({
routeAction
});
浏览器调试输出
routeAction: {"type":"@@redux/INITx.t.b.e.s"} index.js:6:12
routeAction: {"type":"@@redux/PROBE_UNKNOWN_ACTION0.c.1.k.j.c"} index.js:6:12
routeAction: {"type":"@@redux/INITx.t.b.e.s"} index.js:6:12
Mapping this: {"routeAction":{}} App.js:64:10
App is rendering... App.js:24:12
Props in app: {} App.js:25:12
src: undefined/pic.jpg App.js:27:12
props: {"history":{"length":2,"action":"POP","location":{"pathname":"/","search":"","hash":""}},"location":{"pathname":"/","search":"","hash":""},"match":{"path":"/","url":"/","isExact":true,"params":{}}} Home.js:15:12
routeAction: {"type":"LOAD_SCHOOL_DATA"} index.js:6:12
Action type match. index.js:9:20
Mapping this: {"routeAction":{"schooldata":{"images":"blah","photos":"bleep"}}} App.js:64:10
routeAction: {"type":"LOAD_SCHOOL_DATA"} index.js:6:12
Action type match. index.js:9:20
Mapping this: {"routeAction":{"schooldata":{"images":"blah","photos":"bleep"}}} App.js:64:10
routeAction: {"type":"LOAD_SCHOOL_DATA"} index.js:6:12
Action type match. index.js:9:20
Mapping this: {"routeAction":{"schooldata":{"images":"blah","photos":"bleep"}}} App.js:64:10
找到问题。在App.js中,mapStateToProps()在状态JSON结构中没有返回一个有效的键,因此,组件的props没有改变。这意味着驱动组件重新渲染的并不是状态的改变,而是它的道具的改变。这就是修复这个小模型的方法:
App.js
const mapStateToProps = (state, props) => {
console.log("Mapping this: %s", JSON.stringify(state));
return (state.routeAction); // Return valid key!
}