Ant*_*rov 1 javascript reactjs react-router react-redux react-router-redux
我正在为一个带有react,redux,react-router和react-router-redux的项目构建一个管理应用程序.React-router是v4.0.0,react-router-redux是v5.0.0-alpha.3(安装npm install react-router-redux@next).我正在尝试的是:
/login并呈现Login组件.对于异步操作,我正在使用redux-thunk.
import React, { Component, PropTypes } from 'react';
import { Provider, connect } from 'react-redux';
import { Route, Switch } from 'react-router-dom';
import { ConnectedRouter, push } from 'react-router-redux';
import Login from './Login';
const App = () => <h1>Dashboard</h1>;
const NotFound = () => <h1>Not found :(</h1>;
class Root extends Component {
// use componentDidMount as recommended here:
// https://facebook.github.io/react/docs/react-component.html#componentdidmount
componentDidMount() {
const { dispatch, user } = this.props;
if (!user) {
dispatch(push('/login'));
}
}
render() {
const { store, history } = this.props;
return (
<Provider store={store}>
<ConnectedRouter history={history}>
<div>
<Switch>
<Route exact path='/' component={App} />
<Route exact path='/login' component={Login} />
<Route component={NotFound} />
</Switch>
</div>
</ConnectedRouter>
</Provider>
);
}
}
Root.propTypes = {
store: PropTypes.object.isRequired,
history: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
user: PropTypes.shape({
email: PropTypes.string.isRequired
})
};
const mapStateToProps = state => ({
ready: state.ready,
user: state.user
});
export default connect(mapStateToProps)(Root);
Run Code Online (Sandbox Code Playgroud)
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import {
loginFormChange,
loginFormSubmit
} from '../actions';
class Login extends Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
const { target } = event,
{ value, name } = target,
{ dispatch } = this.props;
dispatch(loginFormChange({
[name]: value
}));
}
handleSubmit(event) {
event.preventDefault();
const { dispatch, login } = this.props,
{ email, password } = login;
dispatch(loginFormSubmit({
email,
password
}));
}
render() {
const { login } = this.props,
{ email, password } = login;
return (
<form onSubmit={this.handleSubmit}>
<input type="email" name="email" value={email} onChange={this.handleChange} />
<input type="password" name="password" value={password} onChange={this.handleChange} />
<button type="submit">Sign in</button>
</form>
);
}
}
Login.propTypes = {
dispatch: PropTypes.func.isRequired,
login: PropTypes.shape({
email: PropTypes.string.isRequired,
password: PropTypes.string.isRequired
}).isRequired
};
const mapStateToProps = state => ({
login: state.login
});
export default connect(mapStateToProps)(Login);
Run Code Online (Sandbox Code Playgroud)
export const LOGIN_FORM_CHANGE = 'Login form change';
export const LOGIN_FORM_SUBMIT = 'Login form submit';
export const AUTHENTICATE_USER = 'Authenticate user';
export const loginFormChange = data => {
const { email, password } = data;
return {
type: LOGIN_FORM_CHANGE,
email,
password
};
};
export const loginFormSubmit = data => dispatch => {
const { email, password } = data;
return fetch('/api/auth/token', {
headers: {
'Authorization': 'Basic ' + btoa([ email, password ].join(':'))
},
credentials: 'same-origin'
})
.then(response => {
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json();
})
.then(user => {
// this line will throw setState warning:
// Warning: setState(...): Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.
dispatch(authenticateUser(user));
});
};
export const authenticateUser = data => {
const { email } = data;
return {
type: AUTHENTICATE_USER,
email
};
};
Run Code Online (Sandbox Code Playgroud)
我想指出我正在使用推荐的异步操作方法,如redux文档中所述.为简洁起见,我不会发布我的减速机.最后:
import React from 'react';
import { render } from 'react-dom';
import { createStore, applyMiddleware } from 'redux';
import createHistory from 'history/createBrowserHistory';
import { routerMiddleware } from 'react-router-redux';
import thunk from 'redux-thunk';
import createLogger from 'redux-logger';
import reducers from './reducers';
import Root from './containers/Root';
const history = createHistory(),
middleware = [
routerMiddleware(history),
thunk
];
if (process.env.NODE_ENV !== 'production') {
middleware.push(createLogger());
}
const store = createStore(
reducers,
applyMiddleware(...middleware)
);
render(
<Root store={store} history={history} />,
document.getElementsById('root')
);
Run Code Online (Sandbox Code Playgroud)
因此loginFormSubmit,当它尝试调度同步 authenticateUser操作时,警告会在异步操作中抛出.此外,它只在重定向后发生.我尝试了不同的重定向方法:
push 来自react-router-reduxRedirect 来自react-router的组件我也试图把异地转接呼叫(componentWillMount,componentDidMount,componentWillReceiveProps,有条件的渲染组件的内部,使用条件PrivateRoute的描述组件反应路由器文档等),但似乎没有任何工作.
如果首先没有重定向(例如,用户打开/login页面而不是受保护的页面),则没有警告.
非常感谢任何有关该问题的帮助.
我有同样的问题,基本上它是来自react-router-redux v5.0.0-alpha.2和alpha.3的ConnectedRouter的错误
过去几天它一直在积极讨论,但现在已经修复了alpha 4并且问题已经结束:
https://github.com/ReactTraining/react-router/issues/4713
| 归档时间: |
|
| 查看次数: |
751 次 |
| 最近记录: |