简体   繁体   English

未更新 Redux state 以使用 mapStateToProps 反应组件

[英]Not getting updated Redux state to React component with mapStateToProps

I have a simple testing code to learn redux / react and async API calls with thunk Problem Im having is that I call dispatch in component, which makes a call to API and gets a valid response.我有一个简单的测试代码来学习 redux / 反应和异步 API 调用与 thunk 问题我遇到的是我在组件中调用调度,它调用 API 并获得有效响应。

I console log action.payload inside reducer and I see its a valid response.我在 reducer 中控制台记录 action.payload,我看到它是一个有效的响应。 It should update state.events in my code.它应该在我的代码中更新 state.events。

In my App component I use mapStateToProps and send events: state.events在我的 App 组件中,我使用 mapStateToProps 并发送事件:state.events

As I understand when state gets update It should send new props to my Component, but when I click button in my component to log the props it gets, events is still an empty array?据我了解,当 state 获得更新时,它应该向我的组件发送新的道具,但是当我单击组件中的按钮以记录它获得的道具时,事件仍然是一个空数组吗? What is wrong here?这里有什么问题?

Index.js索引.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'
import './index.css';
import App from './components/App';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

const initialState = {
    events: [],
    isViewingEvent : false,
    eventIndex : 0,
    eventProducts : []
}

//STORE
function reducer(state = initialState, action) {
  switch(action.type) {
    case "GETEVENTS":
        {        
          state.events = action.payload;
          console.log(action.payload)
        };

    default:
      return state;
  }
}

const store = createStore(
  reducer,
  applyMiddleware(thunk)
  );


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

App.js应用程序.js

import { Component } from 'react';
import { connect } from 'react-redux'


class App extends Component {
  
  handleClick () {
    console.log(this.props)    
    this.props.getEvents();
    
  }

  render()  {
    console.log(this.props)
    return(
      <div>
        <header>
          <button onClick={()=> this.handleClick()}>TEST</button>
          <p>{}</p>
        </header>
      </div>
    )
  }
}

const getEvents = () => async (dispatch, getState) => {
    
  const response = await fetch("API URL", {
    method: 'get',
    headers: {'Content-Type':'application/json','Accept': 'application/json'}
    })
    .then(function(response) {
    
        return response.json();         
    })

    dispatch({ type: 'GETEVENTS', payload: response})
}


const mapStateToProps = (state) => {
  console.log(state);
  return {
    events: state.events
  }
}

const mapDispatchToProps = (dispatch) => {  
  return {
    getEvents: () => dispatch(getEvents())
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(App);

Console output when I click button.单击按钮时控制台 output。 I see valid response from API and this should update my state.我看到来自 API 的有效响应,这应该会更新我的 state。 Why are component props showing still events as empty array?为什么组件道具将静止事件显示为空数组?

Picture from console图片来自控制台控制台日志

I can see in your reducer is that you haven't return state.我可以在你的减速器中看到你没有返回 state。

//STORE
function reducer(state = initialState, action) {
  switch(action.type) {
    case "GETEVENTS":
        {        
          //don't need to do in this way it mutate you state.
          //state.events = action.payload;
          console.log(action.payload)
          return  {...state, events: action.payload}
        };

    default:
      return state;
  }
}

Your reducer is not returning a new state object, but just modifying the existing state.您的减速器不会返回新的 state object,而只是修改现有的 state。 Since redux decides to rerender on the basis of lastState !== currentState , this is now doing lastState !== lastState and will never rerender.由于 redux 决定在lastState !== currentState的基础上重新渲染,因此现在正在执行lastState !== lastState并且永远不会重新渲染。

In modern Redux, Redux Toolkit's createSlice does this "for you" in a transparent way, but you are using a way outdated style of redux.在现代 Redux、Redux Toolkit 的createSlice以透明的方式“为您”执行此操作,但您使用的是过时的 Z7490FE17CAEC373F2299D65B6E20E880 样式。 You are probably following an outdated tutorial to learn redux and I highly recommend to learn modern redux from the official Redux tutorials您可能正在遵循一个过时的教程来学习 redux,我强烈建议您从官方 Redux 教程中学习现代 redux

If for whatever reason you are stuck with writing vanilla redux, read up on Immutable update Patterns如果由于某种原因您坚持编写 vanilla redux,请阅读不可变更新模式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM