【问题标题】:React- redux non re-rendering with prop changeReact-redux 不重新渲染道具更改
【发布时间】:2018-08-18 20:52:50
【问题描述】:

我不明白为什么在成功操作和存储更新后 react 没有重新渲染。我不认为我正在改变我的减速器中的状态,因为我在我的反应组件中执行所有算术,然后通过调度发送对象。我的反应组件已连接并连接了 mapStateToProps。任何帮助将不胜感激。

下面是我的反应组件。

const mapStateToProps = (state) =>({


name:state.user.name,
email:state.user.email,
password:state.user.password,
skill:state.user.skill,
goal:state.user.goal,
step1:state.user.step1,
step2:state.user.step2,
step3:state.user.step3,
step4:state.user.step4,
step5:state.user.step5,
completed:state.user.completed,

})



const mapDispatchToProps = (dispatch) => ({
  callApi: (value, state) => {


var obj = {
date:moment.tz(moment.tz.guess()).format(),
post:state.post,
email:state.email,
completed:(parseFloat(state.completed) + .75),
}

    API.addPost(obj)
    .then(function(res){
      dispatch(updateUser(res.data))
    })
  }

})
export default connect(mapStateToProps,mapDispatchToProps)(YourPage);

我的减速器

import {UPDATE_USER, CREATE_USER,CREATE_SKILL,CHECK_USER} from '../actions/index';


const DEFAULT_STATE =

{
createdAt:"",
name:"",
email:"",
password:"",
skill:"",
goal:"",
step1:"",
step2:"",
step3:"",
step4:"",
step5:"",
posts:[],
completed:0
}


export default function(state = DEFAULT_STATE, action) {
  if (action.error) {
    action.type = 'HANDLE_ERROR'; // change the type
  }
  switch (action.type) {


    case UPDATE_USER:



    return Object.assign({},state,{

    completed:action.payload.completed

    })

【问题讨论】:

  • @Colin,你确定吗?据我所知,prop 的更改会导致重新渲染,除非我们采取措施阻止它。

标签: javascript reactjs redux


【解决方案1】:

您是否检查了您的商店正在更新的开发工具?如果不检查操作是否命中减速器(将 console.log 添加到减速器)并且如果 console.log 没有触发,则可能是您调用了导入的操作,而不是带有调度的操作。确保使用 'this.props.action()' 而不是 'action()' 调用它,除非您对其进行解构。

【讨论】:

  • 感谢您的回复。我确实检查了开发工具,并且确实看到我的商店正在更新。减速器被击中。
【解决方案2】:

你的问题在其他地方

添加 console.logs 以检查以下内容

  1. 动作类型常量
  2. API 响应
  3. reducer 中的默认情况

下面的代码works properly

import React, { Component } from 'react';
import { render } from 'react-dom';
import { createStore, combineReducers } from 'redux';
import { connect, Provider } from 'react-redux';
import moment from 'moment';
import 'moment-timezone';
import './style.css';

const DEFAULT_STATE = {
  createdAt: "",
  name: "",
  email: "",
  password: "",
  skill: "",
  goal: "",
  step1: "",
  step2: "",
  step3: "",
  step4: "",
  step5: "",
  posts: [],
  completed: 0
};

const reducer = function (state = DEFAULT_STATE, action) {
  switch (action.type) {
    case 'update user':
      return Object.assign({}, state, {
        completed: action.payload.completed
      });
    default:
      return state;
  }
}


const reducers = combineReducers({
  user: reducer,
})

const updateUser = (payload) => ({
  type: 'update user',
  payload,
})

const API = {
  addPost: obj => new Promise(resolve => setTimeout(() => resolve({ data: obj }), 500))
}

const mapDispatchToProps = (dispatch) => ({
  callApi: (value, state) => {
    var obj = {
      date: moment.tz(moment.tz.guess()).format(),
      post: state.post,
      email: state.email,
      completed: (parseFloat(state.completed) + .75),
    }

    API.addPost(obj)
      .then(function (res) {
        dispatch(updateUser(res.data))
      })
  }

})

const store = createStore(reducers);

class App extends Component {
  render() {
    console.log(this.props);
    return (
      <div>
        <button onClick={() => this.props.callApi(1, this.props)}>Call API</button>

        <div>Value: {this.props.completed}</div>
      </div>
    );
  }
}

const mapStateToProps = (state) => ({
  name: state.user.name,
  email: state.user.email,
  password: state.user.password,
  skill: state.user.skill,
  goal: state.user.goal,
  step1: state.user.step1,
  step2: state.user.step2,
  step3: state.user.step3,
  step4: state.user.step4,
  step5: state.user.step5,
  completed: state.user.completed,

})

const AppContainer = connect(mapStateToProps, mapDispatchToProps)(App);

render(
  <Provider store={store}>
    <AppContainer />
  </Provider>,
  document.getElementById('root')
);

【讨论】:

  • 感谢您的回复,我将在这些地方添加控制台日志,看看我得到了什么,但据我所知,到目前为止,正确的减速器正在被击中,商店正在更新。
  • 我看到您发布的代码仅使用了 redux 状态,但我在代码中所做的是从 redux 状态设置组件的本地状态。这样做有什么问题吗?
  • 它是多余的,并且在应用级状态更改时需要额外的代码来解释本地状态更新。对于派生的、处理成本高的数据,最好使用reselect。否则只需在 render 中定义更多 consts
猜你喜欢
  • 1970-01-01
  • 2017-07-22
  • 2020-12-24
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
  • 2017-03-26
  • 2021-09-01
  • 2021-12-04
相关资源
最近更新 更多