#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 )