重新渲染组件时,我的状态发生了变化

时间:2019-01-11 21:45:45

标签: reactjs redux

我有一个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

1 个答案:

答案 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
    }
}