我有一个简单的测试代码来学习使用 thunk 的 redux/react 和异步 API 调用 我遇到的问题是我在组件中调用 dispatch,它调用 API 并获得有效响应。
我在 reducer 中控制 log action.payload,我看到它是一个有效的响应。它应该更新我的代码中的 state.events。
在我的 App 组件中,我使用 mapStateToProps 并发送事件:state.events
据我所知,状态何时更新它应该向我的组件发送新的道具,但是当我单击组件中的按钮以记录它获得的道具时,事件仍然是一个空数组? 这里有什么问题?
Index.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
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);
单击按钮时的控制台输出。我看到来自 API 的有效响应,这应该更新我的状态。为什么组件 props 将静态事件显示为空数组?
答案 0 :(得分:2)
我可以在你的减速器中看到你没有返回状态。
//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;
}
}
答案 1 :(得分:0)
您的reducer 不会返回新的状态对象,而只是修改现有状态。由于 redux 决定在 lastState !== currentState
的基础上重新渲染,所以现在正在执行 lastState !== lastState
并且永远不会重新渲染。
在现代 Redux 中,Redux Toolkit 的 createSlice
以透明的方式“为您”执行此操作,但您使用的是一种过时的 redux 风格。您可能正在按照过时的教程学习 redux,我强烈建议您从 the official Redux tutorials
如果您因某种原因坚持编写原版 redux,请阅读 Immutable update Patterns