Ошибка типа: не удается назначить свойство ‘0’ только для чтения объекта ‘[Массив объектов]’

#javascript #react-redux #next.js

#javascript #реагировать-redux #next.js

Вопрос:

Я действительно обеспокоен этой проблемой, в случае, если я пытаюсь использовать слайдер пользовательского интерфейса Material с redux.

здесь компонент слайдера:

 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

  

здесь компонент фильтра с логикой сокращения:

 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:

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

export const filterUpdate = createAction(types.FILTER_UPDATE)
  

Здесь редуктор:

 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
  

Ошибка появляется, когда я включаю логику redux, когда я тестировал с консолью.журнал был в порядке, но при отправке появляется эта ошибка, также это случайная ошибка, потому что я могу проверить отправку 2-3 раза без ошибок, но следующая эта ошибка появляется

Что я могу сделать, чтобы справиться с этим?

Заранее спасибо.

Комментарии:

1. Я уверен, что фрагмент кода может быть уменьшен. Можете ли вы удалить все, что работает нормально, оставив только код, который фактически выдает ошибку?

2. @adrihfly вам удалось это решить?

Ответ №1:

В моем случае не удается выполнить функцию сортировки внутри слайдера. Это потому, что значение, которое я передал в компонент, было доступно только для чтения (неизменяемое). Поэтому, чтобы избежать этой ошибки, я должен передать в значение prop копию массива range. Вот так:

 <Slider
    value={[...range]}
    // ....other props
/>
  

Ответ №2:

Я не уверен, в чем проблема, но ваш редуктор определенно ошибочен. Вы делаете:

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

Вы, вероятно, хотели сделать это:

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

Также вы фактически не извлекаете состояние из хранилища redux. Вы импортируете useSelector и нигде его не вызываете. Независимое useState и useDispatch возвращаемое значение в вашем коде независимы друг от друга.