React Native:Redux-persist,动作结果未被持久化

时间:2017-02-08 15:47:17

标签: javascript reactjs react-native redux react-redux

我有一个带有react-redux,redux-thunk和redux-persist的RN应用程序。

一切都很好,我已经改变了减速器并添加了新动作。但遗憾的是,国家不再坚持下去。无论我触发什么动作,重新加载应用程序后,我都认为它没有坚持下去。

可能导致什么原因?

这是我的行动/减少者:



import { REHYDRATE } from 'redux-persist/constants';
import {Actions as routes} from 'react-native-router-flux';

export const types = {
  GET_COURSES: 'GET_COURSES',
  AUTHENTICATE: 'AUTHENTICATE',
  AUTHENTICATE_FAILED: 'AUTHENTICATE_FAILED',
  GET_EVALUATION: 'GET_EVALUATION',
  GET_EVALUATION_FAILED: 'GET_EVALUATION_FAILED',
  SUBMIT_EVALUATION: 'SUBMIT_EVALUATION',
  SUBMIT_EVALUATION_FAILED: 'SUBMIT_EVALUATION_FAILED',
  BOOK_COURSE: 'BOOK_COURSE',
  UNBOOK_COURSE: 'UNBOOK_COURSE',
  BOOK_COURSE_FAILED: 'BOOK_COURSE_FAILED',
  UNBOOK_COURSE_FAILED: 'UNBOOK_COURSE_FAILED'
};

import Functions from './common/Functions';


export const actionCreators = {
  getEvaluations: (users) => {
    return dispatch => {
      Functions.getEvaluationsAPI(users)
      .then((data)=>{
        const {evaluationsList} = data;
        return dispatch(evaluationSuccess(evaluationsList));
      })
      .catch((e)=>{
        return dispatch(evaluationFailed(e));
      });
    }
  },
  getCourses: (users) => {
    console.log('getting courses, user', users);
    return dispatch => {
      Functions.getCoursesAPI(users)
      .then((data)=>{
        const {courseList, lectureList, schedule, eventList, discussion, coursesArray} = data;
        return dispatch(coursesSuccess(courseList, lectureList, schedule, eventList, discussion, coursesArray));
      })
      .catch((e)=>{
        return dispatch(coursesFailed(e));
      });
    }
  },
  bookCourse: (user, courseId, callback) => {
    return dispatch => {
      Functions.bookCourse(user, courseId, callback)
      .then(()=>{
        Functions.getCoursesAPI([user])
        .then((data)=>{
          const {courseList, lectureList, schedule, eventList, discussion, coursesArray} = data;
          return dispatch(coursesSuccess(courseList, lectureList, schedule, eventList, discussion, coursesArray));
        })
        .catch((e)=>{
          return dispatch(coursesFailed(e));
        });
      })
      .catch((e)=>{
        return dispatch(coursesFailed(e));
      })
    }
  },
  unbookCourse: (user, courseId, callback) => {
    return dispatch => {
      Functions.unbookCourse(user, courseId, callback)
      .then(()=>{
        Functions.getCoursesAPI([user])
        .then((data)=>{
          const {courseList, lectureList, schedule, eventList, discussion, coursesArray} = data;
          return dispatch(coursesSuccess(courseList, lectureList, schedule, eventList, discussion, coursesArray));
        })
        .catch((e)=>{
          return dispatch(coursesFailed(e));
        });
      })
      .catch((e)=>{
        return dispatch(coursesFailed(e));
      })
    }
  },
  submitEvaluation: (user, users, evaluationId, evaluationData, callback) => {
    return dispatch => {
      Functions.submitEvaluation(user, users, evaluationId, evaluationData, callback)
      .then(()=>{
        Functions.getEvaluationsAPI(users)
        .then((data)=>{
          const {evaluationsList} = data;
          return dispatch(evaluationSuccess(evaluationsList));
        })
        .catch((e)=>{
          return dispatch(evaluationFailed(e));
        });
      })
      .catch((e)=>{
        return dispatch(evaluationSubmissionFailed(e));
      })
    }
  },
  authenticate: (logincode, callback) => {
    return dispatch => {
  		Functions.login(logincode)
  		.then((response)=>{
        console.log('authenticate results:', response);
        return dispatch(loginSuccess(response));
      })
      .then(()=>{
        routes.tabbar();
      })
      .catch((e)=>{
        console.log('authenticate error:', e);
        callback(e.message);
        return dispatch(loginFailed(e.message));
      })
  	}
  }
}

const loginSuccess = (response) => {
	return {
		type: types.AUTHENTICATE,
		payload: response
	};
};
const loginFailed = (response) => {
	return {
		type: types.AUTHENTICATE_FAILED,
		payload: {
			error: response
		}
	};
};

const evaluationSuccess = (evaluationsList) => {
  return {
    type: types.GET_EVALUATION,
    payload: {
      evaluations: evaluationsList
    }
  };
};

const evaluationFailed = (e) => {
  return {
    type: types.GET_EVALUATION_FAILED,
    payload: {
      error: e
    }
  };
};

const evaluationSubmissionSuccess = (evaluationsList) => {
  return {
    type: types.SUBMIT_EVALUATION,
    payload: {
      evaluatiosn: evaluationsList
    }
  };
};

const evaluationSubmissionFailed = (e) => {
  return {
    type: types.SUBMIT_EVALUATION_FAILED,
    payload: {
      error: e
    }
  };
};

const coursesSuccess = (courses, lectures, schedule, eventList, discussion, coursesArray) => {
  return {
    type: types.GET_COURSES,
    payload: {
      courses: courses,
      lectures: lectures,
      schedule: schedule,
      events: eventList,
      discussion: discussion,
      coursesArray: coursesArray
    }
  };
};

const coursesFailed = (e) => {
  return {
    type: types.GET_COURSES_FAILED,
    payload: {
      error: e
    }
  };
};

const initialState = {
  rehydrated: false,
  user: null,
  login: false,
  users: {},
  courses: {},
  schedules: {},
  evaluations: {},
  lectures: {},
  goals: {},
  discussions: {},
  attendance: {},
  events: {}
}

export const reducer = (state = initialState, action) => {
  const {user, users, courses, login, schedules, evaluations, goals, discussions, attendance, events, lectures} = state;
  const {type, payload} = action;

  switch (type) {
    case types.GET_COURSES: {
      return {
        ...state,
        courses: payload.coursesArray,
        lectures: payload.lectures,
        schedules: payload.schedule,
        events: payload.events,
        discussions: payload.discussion
      }
    }
    case types.GET_COURSES_FAILED: {
      return {
        ...state
      }
    }
    case types.AUTHENTICATE: {
      let newObj = users;
      newObj[payload.userId] = payload;
      let newCourses = courses;
      newCourses[payload.userId] = [];
      let newschedules = schedules;
      newschedules[payload.userId] = [];
      let newevaluations = evaluations;
      newevaluations[payload.userId] = [];
      let newgoals = goals;
      newgoals[payload.userId] = [];
      let newdiscussions = discussions;
      newdiscussions[payload.userId] = [];
      let newattendance = attendance;
      newattendance[payload.userId] = [];
      let neweventList = events;
      neweventList[payload.userId] = [];
      let newlectures = lectures;
      newlectures[payload.userId] = [];

      return {
        ...state,
        login: true,
        user: payload.userId,
        users: newObj,
        courses: newCourses,
        schedules: newschedules,
        evaluations: newevaluations,
        goals: newgoals,
        discussions: newdiscussions,
        attendance: newattendance,
        events: neweventList,
        lectures: newlectures
      }
    }
    case types.AUTHENTICATE_FAILED: {
      return {
        ...state
      }
    }
    case types.GET_EVALUATION: {
      return {
        ...state,
        evaluations: payload.evaluations
      }
    }
    case types.GET_EVALUATION_FAILED: {
      return {
        ...state
      }
    }
    case types.SUBMIT_EVALUATION: {
      return {
        ...state,
        evaluations: payload.evaluations
      }
    }
    case types.SUBMIT_EVALUATION_FAILED: {
      return {
        ...state
      }
    }
    case types.BOOK_COURSE: {
      return {
        ...state
      }
    }
    case types.BOOK_COURSE_FAILED: {
      return {
        ...state
      }
    }
    case types.UNBOOK_COURSE: {
      return {
        ...state
      }
    }
    case types.UNBOOK_COURSE_FAILED: {
      return {
        ...state
      }
    }
    case REHYDRATE: {
      return {
        ...state,
        rehydrated: true
      }
    }
  }
  return state
}




****更新: 商店配置:



import React from "react";
import { View, AsyncStorage } from 'react-native'
import { applyMiddleware, createStore, compose } from 'redux'
import { Provider } from 'react-redux'
import { persistStore, autoRehydrate } from 'redux-persist'
import thunk from 'redux-thunk'
import createLogger from 'redux-logger'
import { reducer } from './reducers'
import Routes from './Routes'

const logger = createLogger();

const store = createStore(reducer, compose(
  applyMiddleware(
    thunk,
    logger
  )
), autoRehydrate({ log: true }))

persistStore(store, {storage: AsyncStorage})


const Root = () => (
  <Provider store={store}>
    <Routes />
  </Provider>
)

export default Root
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:3)

有时,您尝试调度操作,但您的视图不会更新。为什么会这样?可能有几个原因。

永远不要改变缩减器参数

每次都必须返回新的状态对象。即使你不使用像Immutable这样的库,你也需要完全避免变异。

例如,像这样的reducer是错误的,因为它改变了状态:

_spBodyOnLoadFunctionNames.push("myDocURL");
 function myDocURL() {
  $('.ms-listlink').each(function(){
   var myDocName = $(this).attr('href'), 
       myDocNameHref = 'https://www.example.com' + myDocName;
       myDocLink = '<a href="' + myDocNameHref + '" target="_blank">',
       nextTD = $(this).closest("td").next();
   $(nextTD).wrapInner(myDocLink + '</a>');
 });
}

需要像这样重写:

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      // Wrong! This mutates state
      state.push({
        text: action.text,
        completed: false
      })
      return state
    case 'COMPLETE_TODO':
      // Wrong! This mutates state[action.index].
      state[action.index].completed = true
      return state
    default:
      return state
  }
}

它的代码更多,但它正是Redux可预测和高效的原因。

别忘了拨打电话(行动)

别忘了拨打电话(行动)

确保mapStateToProps正确

您可能正确调度动作并应用减速器,但相应的状态未正确转换为道具。

对于同样的问题,来自redux的完整troubleshooting article