【发布时间】:2018-03-16 19:01:40
【问题描述】:
看到已经有很多这样的线程,仍然找不到任何可以帮助我的情况的东西。我敢打赌,这是一些可变性案例,但我真的不知道它可能在哪里。每个动作都被调度,Reducer 获取所有动作并更新存储 - redux devtools 确认它,但 LoginPage 组件仍然没有得到更新,它只在加载/刷新页面上接收初始状态。 mapStateToProps 仅在安装时调用一次。几天前在不同的页面上遇到了同样的问题,但最终和沮丧我完全重写了它并且不知道修复了什么 - 最终代码对我来说是一样的,唯一我能想到的改变是也许我正在访问商店中的字段错误。
如果有人关心或希望提供帮助,我会很高兴。
代码如下:
LoginPage.js
import React from 'react'
import { connect } from 'react-redux'
import { RoutedComponent } from 'routes/routedComponent'
class LoginPage extends RoutedComponent {
constructor(props, context) {
super(props, context)
}
state = {
loginForm: {
email: '',
password: '',
}
}
onFieldChange = (event) => {
const { name, value } = event.target
this.setState({
loginForm: {
...this.state.loginForm,
[name]: value
}
})
}
render() {
return (
<div>
<input type="email" value={this.state.loginForm.email} onChange={this.onFieldChange} />
<input type="password" value={this.state.loginForm.password} onChange={this.onFieldChange} />
{this.props.hasFailed && <h4>Something is wrong</h4>}
{this.props.isLoading && <h4>Logging in...</h4>}
{this.props.hasLoggedIn && <h4>You are logged in</h4>}
</div>
)
}
}
function mapStateToProps ({ user }) {
console.log(user)
return {
hasLoggedIn: user.hasLoggedIn,
hasFailed: user.hasFailed,
isLoading: user.isLoading,
}
}
const mapDispatchToProps = (dispatch) => {
return {
login: params => dispatch(loginUser(params))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(LoginPage)
减速器
const initialState = {
isLoading: false,
hasFailed: false,
}
export function usersReducer(state = initialState, action) {
console.log(state)
switch(action.type) {
case LOGGING_USER:
return {
...state,
isLoading: true,
}
case LOGIN_SUCCESS:
return {
...state,
hasLoggedIn: true,
isLoading: false,
}
case LOGIN_FAILURE:
return {
...state,
hasFailed: true,
isLoading: false
}
default: return state
}
}
登录用户操作
export function loginUser(credentials) {
return dispatch => {
dispatch(loggingUser())
tryToLogUser(dispatch, credentials)
}
}
tryToLogUser 函数
export function tryToLogUser(dispatch, credentials) {
fetch(`${process.env.API_URL}auth/token/`, {
body: JSON.stringify(credentials),
headers: {
'content-type': 'application/json'
},
method: 'POST'
})
.then((response) => {
if (!response.ok) {
throw Error(response.statusText)
}
return response
})
.then((response) => response.json())
.then((tokenData) => {
localStorage.setItem('accessToken', tokenData.access_token)
dispatch(loginSuccess())
})
.catch((error) => dispatch(loginFailure()))
}
以及我结合减速器的方式
export const makeRootReducer = (asyncReducers) => {
return combineReducers({
layout,
router,
notifications,
resources: resourcesReducer,
user: usersReducer,
...asyncReducers
})
}
路由组件
export class RoutedComponent extends React.Component{
getLayoutOptions() { return {} };
componentDidMount() {
const options = this.getLayoutOptions();
if(this.props.setCurrentPageSettings) {
this.props.setCurrentPageSettings(options);
}
// Apply the layout settings from the ones provided in the URL
if(this.props.location.query) {
const urlSettings = _.mapObject(this.props.location.query,
val => autocast(val));
this.props.setLayoutSettingsSafe(urlSettings);
}
// Go to Top
window.scrollTo(0, 0);
}
}
// Attach restoreSettings action to the Component
export function connect(mapStateToProps = () => ({}), mapActionCreators ={}) {
const extendedActionCreators = Object.assign([], mapActionCreators, {
setCurrentPageSettings,
setCurrentPageSettingsLiteral,
setLayoutSettingsSafe
});
return redux.connect(mapStateToProps, extendedActionCreators);
};
【问题讨论】:
-
RoutedComponent看起来像什么?是PureComponent还是实现shouldComponentUpdate? -
@TylerSebastian 为其添加了代码。它似乎在另一个组件中工作,与这个非常相似
-
改为这样导入:
import RoutedComponent from 'routes/routedComponent'。您当前正在导入未连接的组件。 -
@Oblosys 几乎 - 也没有默认导出。他需要换成
export default function ... -
很好,这段代码只是导出
connect。整个最后导出应替换为const extendedActionCreators = ..和export default redux.connect(null, extendedActionCreators)(RoutedComponent);。