使用 redux 响应原生 axios api 调用
Posted
技术标签:
【中文标题】使用 redux 响应原生 axios api 调用【英文标题】:React native axios api calls with redux 【发布时间】:2019-10-02 21:13:02 【问题描述】:我正在努力在 React Native 中使用 redux 和 axios 进行基本的 api 调用设置。
这是我的减速器 index.js
import combineReducers from 'redux'
import LibaryReducer from './LibraryReducer'
import ImportLibraryReducer from './ImportLibraryReducer'
let defaultState =
card: null
const mainReducer = (state = defaultState, action) =>
if(action.type === "CHANGE_CARDS")
return
...state,
card: action.card
else
return
...state
export default mainReducer
这是我的操作 index.js
import axios from "axios"
export function loadCards()
return(dispatch)=>
return axios.get('http://localhost:4000/reports')
.then(response =>
dispatch(changeCards(response.data))
)
export function changeCards(cards)
return
type: "CHANGE_CARDS",
card: card
这是我的 app.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
*/
import React, Component from 'react';
import Platform, StyleSheet, Text, View from 'react-native';
import MainPage from './components/MainPage'
import Header from "native-base"
import Card from './components/Card'
import Provider from 'react-redux'
import createStore, applyMiddleware from 'redux'
import thunk from 'redux-thunk'
import reducers from './reducers'
const store = createStore(reducers, applyMiddleware(thunk))
type Props = ;
export default class App extends Component<Props>
render()
return (
<Provider store=store>
<View>
<Header ><Text>hello</Text></Header>
<Card />
</View>
</Provider>
);
最后,这是我试图从 api 调用中检索数据的地方:
import React, Component from 'react';
import Text, View from 'react-native';
import Collapse,CollapseHeader, CollapseBody, AccordionList from 'accordion-collapse-react-native';
import connect from 'react-redux'
import * as actions from '../actions'
class Card extends Component
render()
const titleStyle =
backgroundColor: '#edeeef',
fontWeight: "bold",
color: '#454647',
fontSize: 16,
left: 8,
fontFamily: 'Ionicons',
top: 10
const descMarkStyle =
left: 8,
top: 4,
fontFamily: 'Ionicons',
color: '#454647',
fontSize: 16
console.log('in the render', this.props)
return (
<View>
<Collapse >
<CollapseHeader>
<View
style=
backgroundColor: '#edeeef',
height: 38,
postion: 'absolute',
borderBottomWidth: .5,
borderBottomColor: '#black'
>
<Text style=titleStyle>
test
</Text>
</View>
</CollapseHeader>
<CollapseBody>
<Text style=descMarkStyle>test</Text>
<Text style=descMarkStyle>test</Text>
</CollapseBody>
</Collapse>
</View>
);
function mapStateToProps(state)
return
state
;
export default connect(mapStateToProps)(Card);
当我尝试在上面的组件中控制台记录 this.props 时,我得到卡的默认状态:null 而没有运行 api:https://imgur.com/a/acB40KU
我是 redux 的新手,我觉得我缺少一些明显的东西。
【问题讨论】:
您似乎没有在任何地方调用您的操作。 我应该在哪里调用它? 【参考方案1】:您应该在Card
组件的componentDidMount
生命周期方法中触发您的操作。此外,您可以在导入和 connect
中解构您的操作。
import loadCards from '../actions'
class Card extends Component
componentDidMount()
this.props.loadCards()
在connect
:
export default connect(mapStateToProps, loadCards )(Card);
同样在changeCards
操作中:
card: cards
【讨论】:
【参考方案2】:以下是如何通过 4 个步骤设置带有 redux 钩子和 react-native 的 axios:
源代码:https://github.com/trackmystories/Redux-hooks-counter-app-with-axios.
第 1 步:
创建一个actions.js文件:
actions.js
export const TOTAL_COUNT = "TOTAL_COUNT";
export const totalCount = (data) => (
type: TOTAL_COUNT,
data,
);
第 2 步:
定义和组合你的减速器:
reducer.js
import combineReducers from "redux";
import TOTAL_COUNT from "./actions";
let dataState = data: [] ;
const total_counts = (state = dataState, action) =>
switch (action.type)
case TOTAL_COUNT:
return ...state, data: action.data ;
default:
return state;
;
const counter = (state = 0, action) =>
switch (action.type)
case "ADD":
return state + 1;
case "SUBTRACT":
return state - 1;
default:
return state;
;
const rootReducer = combineReducers(
counter,
total_counts,
);
export default rootReducer;
第 3 步
创建一个 axios 获取请求并按照下面示例中的定义放置请求,然后分派和获取数据。
有了钩子,你不需要使用 connect mapStateToProps 和 dispatchStateToProps 和 redux 钩子,而是使用 useDispatch, useSelector 。
我们可以直接在按钮内部传递“ADD”和“SUBTRACT”操作,无需定义action.js文件。
CounterComponent.js
import React, useEffect, useState from "react";
import StyleSheet, Text, View, ActivityIndicator from "react-native";
import ActionButton from "./ActionButton";
import SubmitButton from "./SubmitButton";
import useDispatch, useSelector from "react-redux";
import axios from "axios";
import totalCount from "../actions";
export default function CounterComponent()
const dispatch = useDispatch();
const [isFetching, setIsFetching] = useState(false);
const total_counts = useSelector((state) => state.total_counts);
const counter = useSelector((state) => state.counter);
const data = total_counts;
useEffect(() => getTotalCount(), []);
const getTotalCount = () =>
setIsFetching(true);
let url = "https://url.firebaseio.com<name>.json";
axios
.get(url)
.then((res) => res.data)
.then((data) => dispatch(totalCount(data)))
.catch((error) => alert(error.message))
.finally(() => setIsFetching(false));
;
const onSubmit = (counterState) =>
let url = "https://url.firebaseio.com<name>.json";
axios.put(url, counterState).then((response) =>
console.log(response);
);
;
return (
<View>
<ActionButton
onPress=() =>
dispatch(
type: "SUBTRACT",
)
title="subtract"
/>
<View>
isFetching ? (
<ActivityIndicator />
) : (
<View>
<Text>
Current state:
data.counter ? data.counter : counter
</Text>
</View>
)
</View>
<ActionButton
onPress=() =>
dispatch(
type: "ADD",
)
title="add"
/>
<SubmitButton
onPress=onSubmit(
counterState: counter,
)
title="Submit"
/>
</View>
);
第 4 步:
最后将您的 RootReducer 链接到 createStore 并将其传递给 Provider。
import React from "react";
import Text, View from "react-native";
import Provider from "react-redux";
import createStore from "redux";
import CounterComponent from "./src/components/CounterComponent";
import rootReducer from "./src/reducer";
const store = createStore(rootReducer);
export default function App()
return (
<View>
<Text>Counter example with Redux Hooks and Axios</Text>
<Provider store=store>
<CounterComponent />
</Provider>
</View>
);
【讨论】:
以上是关于使用 redux 响应原生 axios api 调用的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 ReactJs、Axios、Redux 渲染/显示从 api 获取的数据
使用 axios 和 Redux Saga 调用 API 总是返回 undefined
将错误响应拦截器放在 redux-axios-middleware 上