vla_doss
@vla_doss
Веб-разработчик

TypeError: «current» is read-only в React в скомпилированной версии?

Есть участок кода в React:
import React, {Component} from 'react';
import {Link} from 'react-router-dom';
import apiCall from '../../functions/apiCall';
import './Apps.css';
import Swiper from "swiper";
import LoadingIcon from '../../assets/LoadingIcon';
import "swiper/swiper-bundle.css";
import {produce} from 'immer'
import 'swiper/components/navigation/navigation.min.css';
import "swiper/components/pagination/pagination.min.css"
import SwiperCore, {
  Pagination,
  Navigation
} from 'swiper/core';
SwiperCore.use([Pagination, Navigation]);
let curSwiper;
const ifNoApps = <div className="Apps_NoApps"><svg xmlns="http://www.w3.org/2000/svg" fill="var(--text)" viewBox="0 0 24 24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z"/></svg><p>Вы ещё не добавили ни одного приложения.</p></div>
const loadingContent = <LoadingIcon color="var(--brand)"/>;
export default class Apps extends Component {
    constructor(props) {
        super(props);
        this.state = {
            content:loadingContent,
            loading:true,
            swiperProps:{
            },
            editModeEnabled:false,
            swiperKey:1,
            swiper:null
        }
        this.switchEditing = this.switchEditing.bind(this);
        this.dragSrcEl = null; 
this.handleDragStart = this.handleDragStart.bind(this);
this.handleDragOver = this.handleDragOver.bind(this);
this.handleDragEnter = this.handleDragEnter.bind(this);
this.handleDragLeave = this.handleDragLeave.bind(this);
this.handleDrop = this.handleDrop.bind(this);
this.handleDragEnd = this.handleDragEnd.bind(this);
this.refs = null;

    }
    handleDragStart(e) {
        if(e.target.tagName === 'IMG' || e.target.tagName === 'P'){

            this.dragSrcEl = e.target.parentNode.parentNode;
        }
        else{

        this.dragSrcEl = e.target;
        }
        
        e.target.style.opacity = '0.4';
      }
    
    handleDragOver(e) {
        if (e.preventDefault) {
          e.preventDefault();
        }
    
        
        return false;}
      
    handleDragEnterNext(){
        curSwiper.slideNext();
    }
    
    handleDragEnterPrev(){
        curSwiper.slidePrev();
    }
  handleDragEnter(e) {
        e.target.classList.add('over');
    
      }
    
     handleDragLeave(e) {
         
        e.target.classList.remove('over');
        }
      
    
      handleDrop(e) {
        
        if (e.stopPropagation) {
          e.stopPropagation();
        }
        
        if (this.dragSrcEl !== e.target) {
            
           
            let appIdForMain;
            const appIdForSecond = this.dragSrcEl.getAttribute('data-id'),secondContent = this.dragSrcEl.innerHTML;
            if(e.target.tagName === 'IMG' || e.target.tagName === 'P'){
                const thisContent =e.target.parentNode.parentNode.innerHTML;

            appIdForMain = e.target.parentNode.parentNode.getAttribute('data-id');
            e.target.parentNode.parentNode.innerHTML = secondContent;
                this.dragSrcEl.innerHTML = thisContent;
                
            }
            else{ 
                
                const thisContent = e.target.innerHTML;
         appIdForMain = e.target.getAttribute('data-id');
                e.target.innerHTML = secondContent;
          this.dragSrcEl.innerHTML = thisContent;
          
                }        
            
            document.querySelector(`[data-id="${appIdForSecond}"]`).setAttribute('data-id',appIdForMain)
            
            document.querySelector(`[data-id="${appIdForMain}"]`).setAttribute('data-id',appIdForSecond)
            }
        
        return false;
            }
      
    
      handleDragEnd(e) {
        e.target.style.opacity = '1';
        e.target.setAttribute('data-id',this.dragSrcEl.getAttribute('data-id'))
        e.target.innerHTML = this.dragSrcEl.innerHTML;
        
       this.refs.forEach((ref)=>{
            ref.current.classList.remove('over');
        })
        
      }
      switchEditing(){
          if(this.state.editModeEnabled === true){
            let apps = '';
            if(this.refs.forEach){
            this.refs.forEach((ref)=>{
                 apps += ref.current.getAttribute('data-id') + ';';
             })
             apps = apps.slice(0, -1);
             apiCall('setapps',{apps}).then(response => {
             })
            }
            this.setState(produce(draft => {
                draft.swiperKey = 1;
                draft.editModeEnabled = false;
            }))
          }
          else{
            this.setState(produce(draft => {
              draft.swiperProps = {
                
                noSwipe:true,
                  observer: true,
                  observeParents: true,
                  
                  navigation: {
                      nextEl: '.swiper-button-next',
                      prevEl: '.swiper-button-prev',
                    },
                  };
              draft.swiperKey = 2;
              draft.editModeEnabled = true;
          }))
          }
        }
      componentDidMount() {
        apiCall('me').then(response => {
            let apps = response.data.preferences.apps;
            apps = apps.split(';');
            if(apps[0] === ''){
            this.setState(produce(draft => {draft.content = <div className="swiper-slide">{ifNoApps}</div>; draft.loading = false }))
            }
            else{
            const appsContent = [];
let itemsPassed = 0;
this.refs = []
          apps.forEach((appId,index) => {
              itemsPassed++;
                const appPath = 'https://api.yundu.co/app/'+appId;
                let appName;
                fetch(appPath+'/yundu-manifest.json').then(response => response.json()).then(response => {
                   appName = response.name;
                    this.refs.push(React.createRef())
                appsContent.push(
                      <div className="Apps_App" data-id={appId} draggable={this.state.editModeEnabled} ref={this.refs[index]} onDragStart={this.handleDragStart} onDragEnter={this.handleDragEnter} onDragOver={this.handleDragOver} onDragLeave={this.handleDragLeave} onDrop={this.handleDrop} onDragEnd={this.handleDragEnd}>
                        <Link key={index} to={'/app/'+appId}><img src={appPath + '/icon.png'} alt="icon" />
                          <p>{appName}</p>
                        </Link>
                      </div>
                    )
                }).catch(err => {
                }).then(()=>{
                if(itemsPassed === apps.length){
                    let cuttedAppsContent = [];
                    for (let i = 0; i < appsContent.length; i += 6) {
                        cuttedAppsContent.push(<div className="swiper-slide" key={i}><div className="Apps_page"><div onDragEnter={this.handleDragEnterPrev} className="pageTrigger prevPageTrigger"></div>{appsContent.slice(i, i + 6)}<div onDragEnter={this.handleDragEnterNext} className="pageTrigger nextPageTrigger"></div></div></div>);
                      }
                    
            this.setState(produce(draft => { draft.content = cuttedAppsContent; draft.loading = false }))
           
                }})
    })
  }
})
}
    render(){
      curSwiper =  new Swiper('.swiper-container', {
        direction: 'horizontal',
        pagination: {
          el: '.swiper-pagination',
        },
      noSwipingClass:'disabled_swiping',
        ...this.state.swiperProps
      })
    return(
      <>
        <div className="Apps">
       
        <div className="swiper-container">
  <div className={"swiper-wrapper" + (this.state.editModeEnabled ? ' disabled_swiping' : '')}>
  
{this.state.loading === true ? <div className="swiper-slide Apps_loading">{loadingContent}</div> : this.state.content}
    
  </div>
  <div className="swiper-pagination"></div>

  <div className="swiper-button-prev"></div>
  <div className="swiper-button-next"></div>
  <div className="Apps_StoreButton" style={{display:this.state.editModeEnabled ? 'none' : 'block'}} onClick={this.props.toggleStoreModal}><svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="48px" viewBox="0 0 24 24" width="48px" fill="var(--bottom-icon)"><g><rect fill="none" height="24" width="24"/><path d="M18,6h-2c0-2.21-1.79-4-4-4S8,3.79,8,6H6C4.9,6,4,6.9,4,8v12c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V8C20,6.9,19.1,6,18,6z M10,10c0,0.55-0.45,1-1,1s-1-0.45-1-1V8h2V10z M12,4c1.1,0,2,0.9,2,2h-4C10,4.9,10.9,4,12,4z M16,10c0,0.55-0.45,1-1,1 s-1-0.45-1-1V8h2V10z"/></g></svg></div>
        <div className="Apps_EditButton" onClick={this.switchEditing}><svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 0 24 24" width="48px" fill="var(--bottom-icon)"><path d="M0 0h24v24H0z" fill="none"/><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg></div>
        
</div>
        
        </div>
        </>
        
    )
    }
}

(Делаю проект на React первый раз, извините за возможно плохой код)
Ошибка происходит в componentDidMount.

При запуске на localhost все работает хорошо, но когда я открываю уже скомпилированную версию вылезает четыре ошибки:
TypeError: "current" is read-only
TypeError: "current" is read-only
Uncaught TypeError: "current" is read-only
Uncaught (in promise) TypeError: "current" is read-only

Каждая ссылается на 201 строчку, тоесть вот эту:
this.setState(produce(draft => { draft.content = cuttedFinal; draft.loading = false }))

Я попробовал вместо cuttedFinal поставить null, все заработало. Причем никакого current в строке нет.
В чём проблема?
  • Вопрос задан
  • 76 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы