2017-02-05 5 views
1

Я извлекаю api с аксиомами, и действие запускается после действия «persist/REHYDRATE», что приводит к следующему «redux-persist/autoRehydrate: 1 действие было выполнено уволен до завершения регидратации .... »Состояние Redux Persist не сохраняется при извлечении api с использованием axios

Если я удалю чириканье по одному, а затем обновить свой браузер, он не сохранит состояние. Не похоже, чтобы взломать этот ..

Client.js

import React from 'react'; 
import { render } from 'react-dom'; 
import { Provider } from "react-redux" 
import { compose, applyMiddleware, createStore } from 'redux'; 
import logger from "redux-logger" 
import thunk from "redux-thunk" 
import promise from "redux-promise-middleware" 
import {persistStore, autoRehydrate} from 'redux-persist' 
import tweetApp from "./reducers" 
import Layout from "./components/Layout" 
import { REHYDRATE } from 'redux-persist/constants' 
import createActionBuffer from 'redux-action-buffer' 

//const middleware = applyMiddleware(promise(), thunk, logger()) 
let enhancer = compose(
    autoRehydrate({ log: true }), 
    applyMiddleware(
    promise(), thunk, logger(), createActionBuffer(REHYDRATE) 
) 
) 
const store = createStore(
    tweetApp, 
    enhancer 
); 
const persistConfig = { 
    whitelist : ["tweets"] 
}; 
persistStore(store, persistConfig); 

render(
    <Provider store={store}> 
    <Layout /> 
    </Provider>, 
    document.getElementById('app') 
); 

tweetsReducer.js

import {REHYDRATE} from 'redux-persist/constants' 

export default function reducer(state={ 
    tweets: [], 
    fetching: false, 
    fetched: false, 
    error: null, 
    }, action) { 

    switch (action.type) { 
     case "persist/REHYDRATE": { 
     const incoming = action.payload.tweets; // Carts is the name of the reducer 
     if (incoming) return {...state, ...incoming} 
     } 
     case "FETCH_TWEETS": { 
     return {...state, fetching: true} 
     } 
     case "FETCH_TWEETS_REJECTED": { 
     return {...state, fetching: false, error: action.payload} 
     } 
     case "FETCH_TWEETS_FULFILLED": { 
     return { 
      ...state, 
      fetching: false, 
      fetched: true, 
      tweets: action.payload, 
     } 
     } 
     case "ADD_TWEET": { 
     return { 
      ...state, 
      tweets: [...state.tweets, action.payload], 
     } 
     } 
     case "UPDATE_TWEET": { 
     const { id, text } = action.payload 
     const newTweets = [...state.tweets] 
     const tweetToUpdate = newTweets.findIndex(tweet => tweet.id === id) 
     newTweets[tweetToUpdate] = action.payload; 

     return { 
      ...state, 
      tweets: newTweets, 
     } 
     } 
     case "DELETE_TWEET": { 
     return { 
      tweets: [ 
       ...state.tweets.slice(0, action.payload), 
       ...state.tweets.slice(action.payload + 1) 
      ], 
     } 
     } 
    } 

    return state 
} 

tweetsActions.js

import axios from "axios"; 

export function fetchTweets() { 
    return function(dispatch) { 
    axios.get("http://rest.learncode.academy/api/test123/tweets") 
     .then((response) => { 
     dispatch({type: "FETCH_TWEETS_FULFILLED", payload: response.data}) 
     }) 
     .catch((err) => { 
     dispatch({type: "FETCH_TWEETS_REJECTED", payload: err}) 
     }) 
    } 
} 

export function addTweet(id, text) { 
    return { 
    type: 'ADD_TWEET', 
    payload: { 
     id, 
     text, 
    }, 
    } 
} 

export function updateTweet(id, text) { 
    return { 
    type: 'UPDATE_TWEET', 
    payload: { 
     id, 
     text, 
    }, 
    } 
} 

export function deleteTweet(id) { 
    return { type: 'DELETE_TWEET', payload: id} 
} 

layouts.js

import React from "react" 
import { connect } from "react-redux" 
import { fetchUser } from "../actions/userActions" 
import { fetchTweets } from "../actions/tweetsActions" 
import { deleteTweet } from "../actions/tweetsActions" 

@connect((store) => { 
    return { 
    user: store.user.user, 
    userFetched: store.user.fetched, 
    tweets: store.tweets.tweets, 
    }; 
}) 

export default class Layout extends React.Component { 
    componentWillMount() { 
    this.props.dispatch(fetchUser()) 
    this.props.dispatch(fetchTweets()) 
    } 

    fetchTweets() { 
    //this.props.dispatch(fetchTweets()) 
    } 

    deleteTweet(idx, e) { 
    this.props.dispatch(deleteTweet(idx)) 
    } 

    render() { 
    const { user, tweets, i } = this.props; 
    //console.log(this.props) 
    const mappedTweets = tweets.map((tweet, i) => <li key={i}>{tweet.text}<button onClick={this.deleteTweet.bind(this, i)}>delete</button></li>) 

    return <div> 
     <h1>{user.name}</h1> 
     <ul>{mappedTweets}</ul> 
    </div> 
    } 
} 

ОБНОВЛЕНИЕ И ТО ЖЕ ВОПРОС: Я попытался заменить компонент componentWILLMount() на componentDidMount(), и проблема все еще происходит. См вошли выход: enter image description here

ответ

0

Двигайте fetchTweets и fetchUser вызовы componentDidMount, в противном случае весь ваш код выполняется синхронно: от магазина создается для вашего макета быть инстанцирован и оказаны.

componentWillMount вызывается перед рендером, а componentDidMount вызывается после того, как компонент был отображен в первый раз.

+0

дал это желание и все еще не повезло. См. Выше, я обновил ответ. – user992731