我几天来一直在寻找答案而且它真的很令人沮丧。我刚刚开始学习React,并遇到了这个麻烦: 我有一个项目reducer就是这个(projectReducers.js):
const projectReducer = (state = {
fetching: false,
fetched: false,
item: {},
items: []
}, action) =>
{
switch(action.type){
case 'GET_PROJECT_START':{
state = { ...state, fetching: true};
}
break;
case 'GET_PROJECT_RECEIVED':{
state = {...state, fetching: false, fetched: true, item: action.payload };
}
break;
case 'GET_PROJECT_ERROR':{
state = { ...state, fetching: false, error: action.payload };
}
case 'GET_PROJECTS_START':{
state = { ...state, fetching: true};
}
break;
case 'GET_PROJECTS_RECEIVED':{
state = {...state, fetching: false, fetched: true, items: action.payload };
}
break;
case 'GET_PROJECTS_ERROR':{
state = { ...state, fetching: false, error: action.payload };
}
}
return state
};
export default projectReducer;
P.S。我知道GET_PROJECT_START和GET_PROJECTS_START也是这样做的,我现在把它们分开是为了我自己的清晰度。
动作(projectActions.js):
export function createProject(number){
return {
type: 'CREATE_PROJECT',
payload: number
}
};
export function getProjectStart(){
return {
type: 'GET_PROJECT_START'
}
};
export function getProjectReceived(project){
return {
type: 'GET_PROJECT_RECEIVED',
payload: project
}
};
export function getProjectError(err){
return {
type: 'GET_PROJECT_ERROR',
payload: err
}
};
export function getProjectsStart(){
return {
type: 'GET_PROJECTS_START'
}
};
export function getProjectsReceived(projects){
return {
type: 'GET_PROJECTS_RECEIVED',
payload: projects
}
};
export function getProjectsError(err){
return {
type: 'GET_PROJECTS_ERROR',
payload: err
}
};
我将reducers与combineReducers结合使用并创建store(store.js):
import {createStore, combineReducers, applyMiddleware} from 'redux';
import logger from 'redux-logger';
import mathReducer from './reducers/mathReducer'; //not relevant
import userReducer from './reducers/userReducer'; //not relevant
import projectReducer from './reducers/projectReducer';
export default createStore(
combineReducers({mathReducer, userReducer, projectReducer}),
{},
applyMiddleware(logger()) <- log changes
);
将来自react-redux的Provider中的根组件包装起来以绑定商店(Index.js)
render(
<Provider store={store}>
<App/>
</Provider>,
window.document.getElementById('app')
);
使用connect(App.js)将商店绑定到root app props
class App extends React.Component {
render() {
return (
<Router history={browserHistory}>
<Route path="/login" component={Login}/>
<Route path="/" component={Dashboard}>
<IndexRoute component={Home}/>
<Route path="/home" component={Home}/>
<Route path="/blank" project={this.props.project} projectActions={this.props.projectActions} component={Projects}/>
</Route>
</Router>
)
}
}
const mapStateToProps = (state) => {
return {
math: state.mathReducer,
user: state.userReducer,
project: state.projectReducer
};
};
const mapDispatchToProps = (dispatch) => {
return {
projectActions :{
getProjectStart: () => {dispatch(getProjectStart())},
getProjectReceived: (project) => {dispatch(getProjectReceived(project))},
getProjectError: (err) => {dispatch(getProjectError(err))},
getProjectsStart: () => {dispatch(getProjectsStart())},
getProjectsReceived: (project) => {dispatch(getProjectsReceived(project))},
getProjectsError: (err) => {dispatch(getProjectsError(err))}
}
};
};
export default connect(mapStateToProps, mapDispatchToProps)(App);
然后使用从服务器获取的(Projects.js)中传递的道具:
export default class Projects extends React.Component {
fetchProjects() {
let projectActions = this.props.route.projectActions;
projectActions.getProjectsStart();
console.log(this.props.route.project);
fetch('http://localhost:3000/projects/').then((response)=> {
setTimeout(() => {
projectActions.getProjectsReceived(response.json());
console.log(this.props.route.project);
}, 5000);
})
}
componentWillMount() {
this.fetchProjects();
}
render() {
return (
<div>
<div className="row">
<h1>Projects</h1>
{this.props.route.project.fetching ? <span> receiving data</span> : <span> Not receiving data </span>}
</div>
</div>
)
}
}
这里有趣的事情发生在this.props.route.project永远不会更新span-&gt;不接收数据永远不会改变,即使我添加了一个巨大的5s延迟。然而,显示(prev state | action | next状态)的redux-logger显示所有正确的更改。我的绑定出错的地方?
答案 0 :(得分:0)
componentWillMount在渲染之前运行,如果你想让一个动作影响你的渲染,你应该使用componentDidMount。