我有一个Web应用程序,可从后端API提取配方。当feed
组件挂载时,我设置了axios get方法以从API接收数据并更新我的redux存储,然后使用mapPropsToState将组件状态更新为与redux存储状态匹配的props。
它在最初呈现组件时起作用,但先移至另一个组件,例如Create Recipe
,然后切换回Feed
组件,内容闪烁一秒钟,然后消失。并显示“没有要显示的食谱”,这是我设置为在没有食谱时显示的内容。
我尝试在componentDidMount方法中使用setState,然后在axios的.then方法中也同时在这两种方法中使用setState。结果还是一样。我还尝试过将状态记录到控制台,它表明我在组件之间来回切换的所有时间都能很好地接收数据,但是数据不会显示在屏幕上。
FEED.JS
import React, {Component} from 'react';
import RecipeCard from './RecipeCard';
import {connect} from 'react-redux';
import {updateRecipes} from '../actions/recipeActions'
import axios from 'axios'
class Feed extends Component {
state = {
recipes: []
};
feedTitleStyle = {
color: 'rgba(230, 126, 34, 1)',
margin: '28px 0'
};
componentDidMount() {
axios.get('http://127.0.0.1:8000/api/recipes/')
.then(res =>{
console.log(res);
this.props.updateRecipesFromAPI(res.data);
this.setState({
recipes: this.props.recipes
})
})
.catch(err => {
console.log(err)
});
let recipes = [...this.state.recipes, this.props.recipes];
this.setState({
recipes
})
}
render() {
const {recipes} = this.state;
console.log(this.props.recipes);
console.log(recipes);
const recipesList = recipes.length ? (
recipes.map(recipe => {
return (
<div className="container" key={recipe.id}>
<div className='col-md-10 md-offset-1 col-lg-9 mx-auto'>
<div className="row">
<div className="col s12 m7">
<RecipeCard recipe={recipe}/>
</div>
</div>
</div>
</div>
)
})
) : (
<div className='center'>No recipes yet</div>
);
return (
<div>
<div className='container'>
<h4 style={this.feedTitleStyle} className='center feed-title'>Feed</h4>
{recipesList}
</div>
</div>
)
}
}
const mapStateToProps = (state) => {
return{
recipes: state.recipes
}
};
const mapDispatchToProps = (dispatch) => {
return {
updateRecipesFromAPI: (recipes) => {dispatch({
type: 'UPDATE_RECIPES',
recipes
}}
}
};
export default connect(mapStateToProps, mapDispatchToProps)(Feed)
这是我的减速器:
const initialState = {
recipes: [],
};
const recipeReducer = (state = initialState, action) => {
switch (action.type) {
case 'UPDATE_RECIPES':
let updatedRecipes = [...state.recipes, action.recipes];
console.log(updatedRecipes[0]);
return {
...state,
recipes: updatedRecipes[0]
};
default:
return state
}
};
export default recipeReducer
答案 0 :(得分:1)
您在 REDUX 和 State 之间游玩,这是错误的,您不应该这样做,相反,理想的解决方案是继续使用REDUX并让REDUX进行异步调用并填写商店,然后利用mapStateToProps
将其加入道具。
使用动作创建者(Async)解决此问题,您应该使用 thunk (Thunk)之类的中间件来实现。
动作创建者:
export const updateRecipesFromAPI_Async = () => { // async action creator
return dispatch => {
axios.post('http://127.0.0.1:8000/api/recipes/')
.then(response => {
console.log(response.data);
dispatch(updateRecipesFromAPI_Success(response.data.name, orderData)); // calls a sync action creator
})
.catch(error => {
console.log(error);
});
}
}
export const updateRecipesFromAPI_Success = (recipes) => { // sync action creator
return {
type: 'UPDATE_RECIPES',
orderData: recipes
}
}