简体   繁体   中英

TypeError: Cannot assign to read only property '0' of object '[object Array]'

Im really rellied about this issue, the case im trying to use a Material UI slider with redux.

here the slider component:

import { Slider } from '@material-ui/core'

const RangeSlider = ({handleRange, range}) => {
    
    const handleChange = (event, newValues) => {
        handleRange(newValues)
    }

    return (
        <Slider
            value={range}
            onChange={handleChange}
            valueLabelDisplay="auto"
            aria-labelledby="range-slider"
            min={0}
            max={100}
        />
    )
}

export default RangeSlider

here the filter component with redux logic:

import {
  Button,
  Typography as Tp,
  Select,
  MenuItem,
  Accordion,
  AccordionDetails,
  AccordionSummary,
} from "@material-ui/core";
import { ExpandMore } from "@material-ui/icons";
import { RangeSlider } from "../components";
import { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { filterUpdate } from "../redux/actions/filter";

const Filter = ({ models }) => {
  const [range, setRange] = useState([0,60]);
  const [modelSelected, setModelSelected] = useState("None");

  const handleRange = (newValue) => setRange(newValue);


  const handleModel = (event) => setModelSelected(event.target.value);

  const dispatch = useDispatch();

  const handleSubmit = () => {
    let filterValues = {
      range,
      modelSelected,
    };
    dispatch(filterUpdate(filterValues));
  };

  return (
    <div className="container mt-3 ">
      <Accordion>
        <AccordionSummary
          expandIcon={<ExpandMore />}
          aria-controls="panel-filter-content"
          id="panel-filter-header"
        >
          <Tp>Sort your search</Tp>
        </AccordionSummary>
        <AccordionDetails className='d-flex align-items-center bg-light pb-3'>
          <div className='col-md-6'>
            <Tp className="mt-3">Pick up a price range</Tp>
            <RangeSlider handleRange={handleRange} range={range} />
          </div>
          <div className="col">
            <div className="col text-center pb-3">
              <Tp className="mt-3">Sort by model</Tp>
              <Select value={modelSelected} onChange={handleModel}>
                {models.map((model) => {
                  return (
                    <MenuItem key={model} value={model}>
                      {model}
                    </MenuItem>
                  );
                })}
              </Select>
            </div>
          </div>

          <div className=" col mt-5 text-center">
            <Button onClick={handleSubmit} variant="outlined" color="primary">
              Submit
            </Button>
          </div>
        </AccordionDetails>
      </Accordion>
    </div>
  );
};

export default Filter;

Redux action logic:

import { createAction } from '@reduxjs/toolkit'
import types from '../types'

export const filterUpdate = createAction(types.FILTER_UPDATE)

Here Reducer:

import { createReducer } from '@reduxjs/toolkit'
import { filterUpdate } from '../actions/filter'

const reducer = createReducer({
    range: [0,60],
    model: 'None'
}, {
    [filterUpdate]: (state, action) => {
        state.range =  action.payload.range
        state.model = action.payload.modelSelected
    }
})

export default reducer

The error appear when i include the redux logic, when i tested with a console.log was fine, but with the dispatch, appear this error, also, its a random error because i can test to dispatch 2-3 times without error, but the next this error appear

What can i do to deal with that?

Thanks in advance.

I am not sure what is the problem, but your reducer is definitely wrong. You do:

const reducer = createReducer({
    range: [0,60],
    model: 'None'
}, {
    [filterUpdate]: (state, action) => {
        state.range =  action.payload.range
        state.model = action.payload.modelSelected
    }
})

You probably meant to do this:

const reducer = createReducer({
    range: [0,60],
    model: 'None'
}, {
    [filterUpdate]: (state, action) => ({
        range: action.payload.range,
        model: action.payload.modelSelected,
    })
})

Also you are not actually pulling state from redux store. You are importing useSelector and not calling it anywhere. Whatever useState and useDispatch return are independent from each other in your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM