【问题标题】:React & Redux - Store updates but component doesn'tReact & Redux - 存储更新但组件没有
【发布时间】: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);

标签: reactjs redux store


【解决方案1】:

我认为你应该在这个地方使用 this.state 通过将 props 分配给组件状态,将组件中的 this.props 分配给组件

【讨论】:

  • 将 state 映射到 props 的重点不就是使用 props 吗?
猜你喜欢
  • 2016-01-13
  • 1970-01-01
  • 2018-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-10
  • 1970-01-01
  • 2021-02-24
相关资源
最近更新 更多