我正在努力学习React和Redux。作为其中的一部分,我正在创建一个简单的应用程序,该应用程序从REST API中检索项目列表。要查询此REST API,我正在使用Axios。目前,我不了解如何实际更新商店中的状态。 Redux的例子令人困惑。
这时,我的应用程序具有以下内容:
/my-app
/actions
items.js
/components
items.js
App.css
App.js
index.css
index.js
store.js
/my-app/actions/items.js
import axios from 'axios';
export GET_ITEMS = 'GET_ITEMS';
export const getItems = (count) => {
axios.get('https://my-app.com/items')
.then(function(response) {
console.log(response.results);
// need to set "response.results" to the value in the store
}
};
/components/items.js
import React from 'react';
import { getItems } from '../actions/items';
class Items extends React.Component {
constructor(props) {
super(props);
this.state = {
items: []
}
}
onButtonClick = () => {
getItems(5);
}
render() {
return {
<div>
<button type="button" onClick={this.onButtonClick}>Load Items</button>
<br />
{this.state.items.map((item) => {
<div>{item.name}</div>
))}
</div>
}
}
}
App.js
import React from 'react';
import Items from './components/items';
function App() {
return {
<div>
<Items></Items>
</div>
};
}
export default App;
/store.js
import { createStore } from 'redux';
import { GET_ITEMS } from './actions/items';
let initialState = {
items: [
{
id:1,
name:'Item A',
description: 'This is a pre-populated item for testing purposes.'
}
]
}
function itemsReducer(state, action) {
switch (action.type) {
case GET_ITEMS:
break;
default:
return state;
}
}
let store = createStore(itemsReducer, initialState);
export default store;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
运行此命令时,我看到带有按钮的屏幕。我可以单击该按钮,但是,我看不到屏幕上显示的项目。如果在控制台窗口中查看,则可以看到通过console.log
语句打印的项目。
如何获取从REST API返回的项目,以及a)在store
中设置这些项目,以及b)使用组件中的存储项目?
非常感谢您的帮助! Redux一直是一个挑战。
答案 0 :(得分:0)
为了简单起见,我将保留此文件夹结构
/my-app
/API
index.js
/state
action-types.js
/actions
items.js
/reducers
items.js
/components
/items
ItemComponent.js
我喜欢将API与状态分开,以更好地分离关注点/控制
API / index.js
import axios from 'axios';
const BASE_URL = 'https://my-app.com/items';
export const getItems = () => {
axios
.get(`${BASE_URL}/items`)
.then(response => response.data)
.catch(error => error);
};
原因,我喜欢这种方法
getItems
API端点而无需调用getItems
操作和状态更新axios
,则无需修改所有操作文件action-types.js
export const GET_ITEMS = 'GET_ITEMS';
/actions/item.js
import * as ACTION_TYPES from '../action-types';
import * as API from '../../API';
const getItems = async count => {
const getItemsResponse = await API.getItems();
return {
type: ACTION_TYPES.GET_ITEMS,
payload: {
items: getItemsResponse.data,
count
}
};
};
export default getItems;
/reducers/item.js
import * as ACTION_TYPES from '../action-types';
const initialState = {
items: [
{
id:1,
name:'Item A',
description: 'This is a pre-populated item for testing purposes.'
}
]
}
const itemsReducer = (state, action) => {
switch (action.type) {
case ACTION_TYPES.GET_ITEMS:
const { items } = action.payload;
return { ...state, items }
break;
default:
return state;
}
}
最后,您可以将connect
中的react-redux
包裹在ItemComponent.js
周围。以下代码应添加到文件中已存在的代码中
ItemComponent.js
const mapDispatchToPtops = {
getItems
}
const mapStateToProp = state =>({
items: state.itemsReducer.items
})
export default connect(mapStateToProp, mapDispatchToPtops)(ItemComponent)