用于在特定索引处插入数组的Redux reducer

时间:2019-07-12 18:07:12

标签: javascript redux react-redux

我正在尝试将数组questions插入到数组中某个state处的index数组中,但是顺序并不总是正确。我期待这样的事情:

[[/*arr 0*/], [/*arr 1*/], [/*arr 2*/], [/*arr 3*/], ...]

但是我不断收到这样的东西:

[[/*arr 0*/], [/*arr 2*/], [/*arr 1*/], [/*arr 3*/], ...]

我尝试遵循官方Redux文档中的this guide,但无济于事。我的减速器如下:

export const questions = (state = [], action) => {
    switch (action.type){
        case SET_QUESTIONS:
            const {questions, index} = action.payload;

            let newArray = state.slice()
            newArray.splice(index, 0, questions);
            return newArray
        case RESET_QUESTIONS:
            return [];
        default:
            return state;
    }
};

我在做什么错了?

编辑:

已要求我显示如何调用动作,因此这是调用动作的代码段。根据所需的长度,这大约循环7次。这些调用是异步的,但我认为这不一定会改变reducer的功能。

axios.post(`${process.env.REACT_APP_SERVER_ENDPOINT}/getQuestionnaireData`, data).then(res => {
  store.dispatch(setQuestions(res.data, index));
  resolve();
}).catch(err => {
  store.dispatch(setError(true));
});

分派的动作如下:

export const setQuestions = (questions, index) => ({
    type: SET_QUESTIONS,
    payload: {
        questions,
        index
    }
})

编辑2:

由于无法进行调度调用(无法强制插入顺序),并且不幸的是,我得到的所有答复都无法解决我的问题,因此我选择了其他解决方案。我最终将我的减速器更改为以下内容:

export const questions = (state = {}, action) => {
    switch (action.type){
        case SET_QUESTIONS:
            const {questions, index} = action.payload;

            //Retrieve the previously stored state
            let newObj = {
                ...state,
            }

            //Create a new object at the step key if it doesn't exist
            if (!newObj[index]) newObj[index] = {};

            //Assign the value at the id key in the step object
            newObj[index] = questions;

            return newObj;
        case RESET_QUESTIONS:
            return {};
        default:
            return state;
    }
};

从那里开始,我最终使用Lodash像数组一样遍历对象。这种方法被证明是非常可靠的,所以我坚持这样做。

感谢大家的回答。我希望他们能为以后可能遇到此问题的其他人工作。

2 个答案:

答案 0 :(得分:1)

实际上,您不是在使用Spread运算符,所以请使用Spread运算符,您可以从以下this link

了解有关Spread运算符的信息。

尝试以下代码

private function product_image(){
    $this->load->library('upload');
    $_FILES['userfile']['name']     = $_FILES['product_image']['name'];
    $_FILES['userfile']['type']     = $_FILES['product_image']['type'];
    $_FILES['userfile']['tmp_name'] = $_FILES['product_image']['tmp_name'];
    $_FILES['userfile']['error']    = $_FILES['product_image']['error'];
    $_FILES['userfile']['size']     = $_FILES['product_image']['size'];
    $this->upload->initialize($this->upload());
    if(!$this->upload->do_upload()):
    $this->load->view('upload_form', $error);
     $this->load->view('footer');
    else:
        $fileData = $this->upload->data();
        $image = "image-".$fileData['file_name'];
    endif;
    return $image;

}

private function product_banner(){
    $this->load->library('upload');
    $_FILES['userfile']['name']     = $_FILES['product_banner']['name'];
    $_FILES['userfile']['type']     = $_FILES['product_banner']['type'];
    $_FILES['userfile']['tmp_name'] = $_FILES['product_banner']['tmp_name'];
    $_FILES['userfile']['error']    = $_FILES['product_banner']['error'];
    $_FILES['userfile']['size']     = $_FILES['product_banner']['size'];
    $this->upload->initialize($this->upload());
    if(!$this->upload->do_upload()):
    $this->load->view('upload_form', $error);
     $this->load->view('footer');
    else:
        $fileData = $this->upload->data();
        $banner = "baner-".$fileData['file_name'];
    endif;
    return $banner;

}

private function upload(){
    $config = array();
    $config['file_name'] = "example_name";
    $config['upload_path']  = APPPATH. '../assets/uploads/';
    $config['allowed_types'] = 'gif|jpg|png';
    $config['max_size']      = '0';
    return $config;
}   

答案 1 :(得分:0)

您需要考虑SET_QUESTIONS数组中的项目少于新state的情况(包括第一次发送index的情况)。

记住这一点,我可能会做这样的事情:

export const questions = (state = [], action) => {
  switch (action.type) {
    case SET_QUESTIONS:
      const { questions, index } = action.payload
      const stateCopy = [...state]
      stateCopy[index] = payload

      return stateCopy
    case RESET_QUESTIONS:
      return []
    default:
      return state
  }
}