【问题标题】:React native axios api calls with redux使用 redux 响应原生 axios api 调用
【发布时间】: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 的新手,我觉得我缺少一些明显的东西。

【问题讨论】:

  • 您似乎没有在任何地方调用您的操作。
  • 我应该在哪里调用它?

标签: reactjs react-native redux axios redux-thunk


【解决方案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>
      );
    }

    【讨论】:

      猜你喜欢
      • 2021-01-06
      • 2018-09-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-11
      • 1970-01-01
      • 2020-04-28
      • 2016-07-21
      • 1970-01-01
      相关资源
      最近更新 更多