Хранилище Redux не обновляет реквизиты компонента

#redux #react-native-android

#redux #react-native

Вопрос:

Я пытаюсь вызвать API из своего магазина, чтобы обновить состояние компонента, получая при этом цену криптовалюты.

Взамен я использую клон своего состояния (nextState здесь), и журнал nextState хорошо заполнен ценой товара, но мой компонент получает только начальное состояние.

Вот код :

Мой компонент

 import React from 'react';
import { StyleSheet, Text, View, Button, ImageBackground,TouchableOpacity, Image } from 'react-native';
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen';
import { connect } from 'react-redux'

class Bitcoin extends React.Component {
   constructor(props){
     super(props);
     this.state = {
    }
    }

componentDidMount() {
    const action = { type: 'PRICES', value: this.state.cryptos}
    this.props.dispatch(action)
    console.log(this.props.cryptos)
}

componentDidUpdate() {
    console.log("Component did Update : ")
    console.log(this.props.cryptos)
}

  render() {
return (
    <View>
        <Text style={styles.title}>Bitcoin !</Text>
        <Text> {this.props.cryptos[0].price} </Text>
    </View>
)
  }
}

const styles = StyleSheet.create({
title: {
    marginTop: wp("10%")
},
});

const mapStateToProps = (state) => {
return {
    cryptos: state.Crypto.cryptos
  }
}

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

export default connect(mapStateToProps, mapDispatchToProps)(Bitcoin)
  

Мой редуктор :

 const initialState = {  cryptos: [
                    {
                        title: "Bitcoin",
                        id: "BTC",
                        price: 0
                    }, {
                        title: "Ethereum",
                        id: "ETH",
                        price: 0
                    }, {
                        title: "Ripple",
                        id: "XRP",
                        price: 0
                    }], toast: 0}

function Crypto(state = initialState, action) {
    let nextState
    switch (action.type) {
      case 'PRICES':
        nextState = {...state}
        fetch('https://min-api.cryptocompare.com/data/pricemulti?fsyms=ETH,BTC,XRPamp;tsyms=EURamp;api_key=c3b60840403013f86c45f2ee97571ffdf60072fafff5c133ed587d91088451b6')
        .then((response) => response.json())
        .then((responseJson) => {
            nextState.cryptos[0].price = responseJson.BTC.EUR.toString()
            nextState.cryptos[1].price = responseJson.ETH.EUR.toString()
            nextState.cryptos[2].price = responseJson.XRP.EUR.toString()
            console.log("NextState :");
            console.log(nextState.cryptos);
            return nextState
        })
        .catch((error) => {
            console.error(error);
        });
        return nextState
    case 'TOAST':
        nextState = {...state}
    default:
        return state
    }
}

export default Crypto
  

Комментарии:

1. Ваш текущий подход противоречит redux. Функция Reducer должна быть чистой функцией. Здесь не допускаются побочные эффекты. Вы должны поместить связанный с сетью код в сам компонент или в создателя действия, используя, скажем, промежуточное программное обеспечение thunk.

Ответ №1:

Добро пожаловать в StackOverflow. Я предполагаю, что вы новичок в Redux workflow. Итак, вот оно.

Действия описывают действие. Редуктор получает действие и указывает, как изменяется хранилище.

Действие должно быть простым объектом javascript. И функции редуктора должны быть чистыми!

Вот что запрещено делать внутри редукторов :

   Mutate its arguments;
  Perform side effects like API calls and routing transitions;
  Call non-pure functions, e.g. Date.now() or Math.random().
  

В вашем примере, путем вызова fetch. Вы выполняете вызов API.

Я приглашаю вас прочитать это руководство, чтобы узнать больше о том, как внедрить вызов API и асинхронность в ваше приложение redux. (https://redux.js.org/advanced/async-actions )