Redux-使用不同文件中的相同功能更新存储

时间:2020-06-09 16:17:54

标签: redux react-redux

对react.js + redux相当陌生,我面临以下难题:

我有多个文件,需要根据商店的当前状态以完全相同的方式更新商店。目前,我只是简单地复制粘贴相同的代码(以及所需的mapStateToProps),然后再次进行干燥。

类似于以下内容,其中getData是生活在动作文件中的Ajax调用,而props.timeAttribute来自mapStateToProps:

props.getData(props.timeAttribute).then((newState) => {
    console.log(newState)
})

这样的功能会放在动作文件中吗?是否可以从该动作文件中读取当前状态?还是通常会创建某种形式的helperFile.js,这样的函数就可以存在并且正在从其他文件中调用?

谢谢!

2 个答案:

答案 0 :(得分:1)

如果文件正在执行相同的操作,则可以,您需要将操作创建者放在单独的文件中并导出。从理论上讲,您可以通过将状态作为参数传递给操作,但是操作背后的原理是,它向您的应用程序宣布发生了某些事情(如返回值的type属性所表示)动作功能)。负责处理type的reducer函数随后会更新状态。

您可以在操作创建者内部访问商店的当前状态,如下所示:

export const testAction = (someParam) => {
  return (dispatch, getState) => {
    const {
     someState,
    } = getState(); //getState gets the entire state of your application

   //do something with someState and then run the dispatch function like this: 
   dispatch(() => {type: ACTION_TYPE, payload: updatedState})




}

我喜欢这种方法,因为它将所有用于访问状态的逻辑封装在一个需要访问它的函数中。

但是请勿在动作创建者内部修改状态!这应该是只读的。您的应用程序状态仅应通过化简函数进行更新。

答案 1 :(得分:1)

是的,建议为您的操作维护一个单独的文件。 以下是我如何使用操作来获取信息并调度操作的示例。

const url = "/api/applications";
fetch(url)
    .then(response => response.json())
    .then(data => this.setState({ applications: data }));

一旦收到调度动作,您就需要一个减速器来捕获该动作并对商店进行更改。 请注意,此reducer必须是纯函数。

export const fetchComments = () => (dispatch) => {
    console.log("Fetch Comment invoked");
    /*you can use your Ajax getData call instead of fetch.
    Can also add parameters if you need */
    return fetch(baseUrl + 'comments')
        .then(response => {
            if (response.ok){
                return response;
            }
            else {
                var error = new Error('Error ' + response.status + ': ' + response.statusText);
                error.response = response;
                throw error;
            }
        },
        error => {
            var errmess = new Error(error.message);
            throw errmess;
        })
        .then(response => response.json())
        .then(comments => dispatch(addComments(comments)))
        .catch(error => dispatch(commentsFailed(error.message)));
}
/* Maintain a separate file called ActionTypes.js where you can store all the ActionTypes as Strings. */
export const addComments = (comments) => ({
    type : ActionTypes.ADD_COMMENTS,
    payload : comments
});

export const comments = (errMess) => ({
    type : ActionTypes.COMMENTS_FAILED,
    payload : errMess
});

别忘了在configureStore()中组合化简器。

export const comments = (state = { errMess: null, comments:[]}, action) => {
  console.log("inside comments");
  switch (action.type) {
    case ActionTypes.ADD_COMMENTS:
      return {...state, errMess: null, comments: action.payload};

    case ActionTypes.COMMENTS_FAILED:
      return {...state, errMess: action.payload};

    default:
      return state;
  }
};

在使用操作的组件中,使用

const store = createStore(
    combineReducers({
        comments
    }),
    applyMiddleware(thunk,logger)
    );

注意将组件导出为

const mapDispatchToProps = dispatch => ({
    fetchComments : () => dispatch(fetchComments()),
})