【问题标题】:Redux store not update after dispatchRedux 存储在调度后不更新
【发布时间】:2018-01-06 04:55:26
【问题描述】:

我试图在渲染之前获取我的组件加载数据,所以我使用 componentWillMount 来调度我的 getTransaction() 操作并获得成功(我将 redux-logger 作为中间件来了解成功或失败)。 问题是我的 redux 商店没有更新。我需要这些数据作为道具传递给子组件。 主要问题在于 Transaction.js 这是我的代码

Transaction.js

import React from "react";
import { connect } from "react-redux"
import { withRouter } from 'react-router-dom';

import { getAuthenticatedUsername } from '../../utils/authorization'
import Layout from "./../layout/Index"
import Table from "../../components/table/Table"

import { getTransaction } from "../../actions/transactionActions"

import "./styles.scss"

function mapStateToProps(state){
  return {
    transaction: state.transaction
  }
}
class Transaction extends React.Component {

  componentWillMount() {
    this.props.dispatch(getTransaction());
  }

  render() {
    console.log(this.props);//transaction not get updated, only get initial state from transactionActions
    return (
      <Layout username={getAuthenticatedUsername()}>
          <Table data={this.props.transaction}/>
      </Layout>
    );
  }
}

export default connect(mapStateToProps)(Transaction);

client.js

import React from "react"
import ReactDOM from "react-dom"
import { Provider } from "react-redux"
import { 
  HashRouter,
  Link,
  Route,
  Redirect
} from 'react-router-dom'

import { isAuthenticated, setAuthorizationToken } from './utils/authorization'

import store from "./store/store"
import Login from "./pages/Login"
import Register from "./pages/Register"
import CatExpense from "./pages/isi/CatExpense"
import CatIncome from "./pages/isi/CatIncome"
import Transaction from "./pages/isi/Transaction"

import "../styles/styles.scss"

setAuthorizationToken(localStorage.jwtToken);

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    isAuthenticated() ? (
      <Component {...props}/>
    ) : (
      <Redirect to={{
        pathname: '/login',
        state: { from: props.location }
      }}/>
    )
  )}/>
)

ReactDOM.render(
  <Provider store={store}>
    <HashRouter>
      <switch>
        <Route exact path="/" component={Login}/>
        <Route path="/login" component={Login}/>
        <Route path="/register" component={Register}/>
        <PrivateRoute path="/transaction" component={Transaction}/>
        <PrivateRoute path="/catincome" component={CatIncome}/>
        <PrivateRoute path="/catexpense" component={CatExpense}/>
        <Redirect path="*" to="/"/>
      </switch>
    </HashRouter>
  </Provider>, document.getElementById('app'));

store.js

import { applyMiddleware, createStore } from "redux";
import axios from "axios";
import { createLogger } from "redux-logger";
import thunk from "redux-thunk";
import promise from "redux-promise-middleware";

import reducer from "../reducers/index";

const middleware = applyMiddleware(promise(), thunk, createLogger());
export default createStore(reducer, middleware);

transactionReducer.js

const initialState = {
  isFetching: false,
  isSuccess: false,
  transaction: {}
}
export default function reducer(state = initialState, action ) {
  switch (action.type) {
    case "GET_TRANSACTION_PENDING": {
      return { ...state, isFetching: true }
      break;
    }
    case "GET_TRANSACTION_REJECTED": {
      return { ...state, isFetching: false, error: action.payload }
      break;
    }
    case "GET_TRANSACTION_FULFILLED": {
      return { ...state, isSuccess: true, transaction: action.payload }
      break;
    }
  }
  return state;
}

transactionActions.js

import axios from "axios"
import jwt from "jsonwebtoken"
import { isAuthenticated } from '../utils/authorization'

export function getTransaction(){
  isAuthenticated();
  return function(dispatch) {
    axios.get("http://localhost:8000/listTransaction")
      .then((response) => {
        dispatch({type: "GET_TRANSACTION_FULFILLED", payload: response.data})
      })
      .catch((err) => {
        dispatch({type: "GET_TRANSACTION_REJECTED", payload: err})
      })
  }
}

【问题讨论】:

  • 您能否展示一下您是如何创建商店并将其提供给组件的
  • 这取决于 reducer 以及如何通过 redux-thunk 分派 action。你能展示一下getTransaction函数吗?
  • @ShubhamKhatri 我已经更新了我的代码先生
  • @vijayst 我已经更新了我的代码先生
  • GET_TRANSACTION_FULFILLED 是否显示在 redux-logger 中?对于这种情况,您还应该将 isFetching 设置为 false。

标签: reactjs react-redux


【解决方案1】:

我自己发现了问题。 实际上数据已经更新,只是有点晚了。在检索数据之前,数据已经作为道具传递给子组件,其中子组件映射为空的数据。这就是导致问题的原因。 所以我把验证如果 null 渲染为 null,否则渲染数据。 子组件获取数据后,会自动重新渲染显示数据。

【讨论】:

    【解决方案2】:

    两件事。首先,您应该根据 React 文档在 componentDidMount 中发送操作。 https://facebook.github.io/react/docs/react-component.html#componentdidmount

    其次,你需要将Redux的mapDispatchToProps()函数传递给你的connect,并传入实际的action。

      const mapDispatchToProps = (dispatch) => {
       return {
        onTodoClick: (id) => {
          dispatch(toggleTodo(id))
        }
       }
      }
    
    export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
    

    What is mapDispatchToProps?

    https://github.com/reactjs/react-redux/blob/master/docs/api.md

    【讨论】:

    猜你喜欢
    • 2021-09-05
    • 2016-06-30
    • 2021-02-24
    • 2020-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多