Форум программистов, компьютерный форум, киберфорум
React/ReactJS
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
4 / 4 / 1
Регистрация: 26.03.2023
Сообщений: 153

Непонятное поведение переменной

31.03.2024, 19:34. Показов 442. Ответов 6

Студворк — интернет-сервис помощи студентам
Всем привет. У меня есть react компонент:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
import React, { useEffect, useRef, useState } from 'react'
import styles from './Card.module.scss'
import { useParams, useLocation, json } from 'react-router';
// -------------------------
import { Header } from '@/components/Header/Header'
import test_img from './images/test_img.jpg'
import { Loader } from '@/components/Loader/Loader.jsx'
import { Slider } from '@/components/Slider/Slider'
import { MenuItem, FormControl } from '@mui/material';
import Select from '@mui/material/Select';
 
export const Card = () => {
  const MuiSelect = React.forwardRef(({property, disabled, onChangeSelect, availableProperties, getSelectSetOption}, ref) => {
    const [option, setOption] = useState('')
 
    useEffect(() => {
      getSelectSetOption(setOption, property)
    }, [])
 
    useEffect(() => {
      option ? onChangeSelect(property) : null
    }, [option])
 
    return (
      <FormControl variant="standard" fullWidth className={styles.Card__muiLabel}>
        <Select
          disabled={disabled}
          ref={ref}
          value={option}
          onChange={(event) => {
            setOption(event.target.value)
          }}>
          {Object.entries(netsProperties[property]).map(([key, value]) => 
            <MenuItem key={key} value={key} disabled={availableProperties ? !availableProperties.includes(parseInt(key)) ? true : false : false}>{value}</MenuItem>
          )}
        </Select>
      </FormControl>
    )
  })
 
  const CardProperties = () => {
    // Я пострался сделать так, чтобы от порядка массива propertiesOrder зависило очередность открытия selects
    let propertiesOrder = ['length', 'width', netsProperties.color ? 'color' : 'thickness']
    let changeFirstProperty = (properties) => { // устанавливает первую сетку из propertiesOrder на false, чтобы она была кликабельна
      for (let property of Object.keys(properties)) {
        property == propertiesOrder[0] ? properties[property] = false : null
      }
      return properties
    }
    let [disabledSelects, setDisabledSelects] = useState(netsProperties.color ? changeFirstProperty({
      length: true,
      width: true,
      color: true,
    }) : changeFirstProperty({
      length: true,
      width: true,
      thickness: true,
    }))
    let selectsRefs = {
      length: useRef(),
      width: useRef(),
      color: useRef(),
      thickness: useRef(),
    }
    let [availableProperties, setAvailableProperties] = useState()
 
    let getSelectedProperties = () => {
      let selectedProperties = {}
      for (let property of propertiesOrder) {
        selectedProperties[property] = selectsRefs[property].current.querySelector('input').value
      }
      return selectedProperties
    }
 
    let checkAvailableProperties = (selectProperty) => { // устанавливам доступные свойства по доступным сеткам
      // получаем доступные сетки, по выбранным свойствам
      let selectedProperties = getSelectedProperties()
      let availableNets = []
      for (let property of Object.keys(selectedProperties)) {
        if (selectedProperties[property]) {
          let netsByProperty = nets.filter(net => net[property] == selectedProperties[property])
          if (availableNets.length == 0) {
            availableNets = netsByProperty
          } else {
            availableNets = availableNets.filter(net => netsByProperty.includes(net))
          }
        }
      }
 
      // преобразуем объект из сеток в объект из доступных свойств
      let newAvailableProperties = {}
      for (let net of availableNets) {
        for (let property of propertiesOrder.slice(propertiesOrder.indexOf(selectProperty)+1)) {
          newAvailableProperties[property] = newAvailableProperties[property] ? 
          new Set([...newAvailableProperties[property], net[property]]) : new Set([net[property]])
          newAvailableProperties[property] = [...newAvailableProperties[property]]
        }
      }
 
      // сравниваем с прошлыми доступными свойствами (availableProperties) и меняем по необходимости newAvailableProperties
      if (availableProperties) {
        for (let property of propertiesOrder) {
          if (availableProperties[property] && !newAvailableProperties[property]) {
            newAvailableProperties[property] = availableProperties[property]
          }
        }
      }
 
      setAvailableProperties(newAvailableProperties)
    }
 
    let onChangeSelect = (selectProperty) => {
      // устанавливаем пустые value для нужных select
      for (let property of propertiesOrder.slice(propertiesOrder.indexOf(selectProperty)+1)) {
        selectsSetOptions[property]('')
      }
 
      // устанавливаем нужные disabledSelects (поля, которые должны быть некликабельны)
      let newDisabledSelects = {...disabledSelects}
      propertiesOrder[propertiesOrder.indexOf(selectProperty) + 1] ? newDisabledSelects[propertiesOrder[propertiesOrder.indexOf(selectProperty) + 1]] = false : null
      for (let property of propertiesOrder.slice(propertiesOrder.indexOf(selectProperty)+2)) {
        newDisabledSelects[property] = true
      }
      setDisabledSelects(newDisabledSelects)
    }
 
    let getSelectSetOption = (setOption, property) => {
      selectsSetOptions = {...selectsSetOptions}
      selectsSetOptions[property] = setOption
    }
 
    useEffect(() => {
      let selectedProperties = getSelectedProperties()
      let getSelectProperty = () => {
        for (let property of propertiesOrder) {
          if (!selectedProperties[property]) {
            return propertiesOrder[propertiesOrder.indexOf(property) - 1]
          }
        }
        return propertiesOrder[propertiesOrder.length-1]
      }
 
      // пересчитываем доступные свойства только если ...
      if (selectedProperties[propertiesOrder[0]]) {
        let selectProperty = getSelectProperty()
        if (selectProperty != propertiesOrder[propertiesOrder.length - 1]) {
          checkAvailableProperties(selectProperty)
        }
      }
    }, [disabledSelects])
 
    return (
      <div className={styles.Card__properties}>
        <div className={styles.Card__property}>
          <strong>Длина</strong>
          <div className={styles.underline}></div>
          <MuiSelect ref={selectsRefs.length} disabled={disabledSelects.length} getSelectSetOption={getSelectSetOption} availableProperties={availableProperties ? availableProperties.length : false} property='length' onChangeSelect={onChangeSelect}/>
        </div>
        <div className={styles.Card__property}>
          <strong>Ширина</strong>
          <div className={styles.underline}></div>
          <MuiSelect ref={selectsRefs.width} disabled={disabledSelects.width} getSelectSetOption={getSelectSetOption} availableProperties={availableProperties ? availableProperties.width : false} property='width' onChangeSelect={onChangeSelect}/>
        </div>
        {netsProperties['color'] ?
          <div className={styles.Card__property}>
            <strong>Цвет</strong>
            <div className={styles.underline}></div>
            <MuiSelect ref={selectsRefs.color} disabled={disabledSelects.color} getSelectSetOption={getSelectSetOption} availableProperties={availableProperties ? availableProperties.color : false} property='color' onChangeSelect={onChangeSelect}/>
          </div>
        : <div className={styles.Card__property}>
            <strong>Толщина</strong>
            <div className={styles.underline}></div>
            <MuiSelect ref={selectsRefs.thickness} disabled={disabledSelects.thickness} getSelectSetOption={getSelectSetOption} availableProperties={availableProperties ? availableProperties.thickness : false} property='thickness' onChangeSelect={onChangeSelect}/>
          </div>}
      </div>
    )
  }
 
  // ------------------------------------------------------
 
  let apiUrl = import.meta.env.VITE_APIURL
  let {netType, cellId, cell} = useParams()
  let [nets, setNets] = useState()
  let [netsProperties, setNetsProperties] = useState()
  let selectsSetOptions = new Set()
 
  let getNetsProperties = (nets, config) => {
    let newNetsProperties = {}
    for (let net of nets) {
      for (let unnecessaryProperty of ['id', 'images', 'price', 'quantity']) {
        delete net[unnecessaryProperty]
      }
      for (let property of Object.keys(net)) {
        if (newNetsProperties[property]) {
          newNetsProperties[property][net[property]] = config[property].filter(variant => variant.id == net[property])[0][property]
        } else {
          newNetsProperties[property] = {}
          newNetsProperties[property][net[property]] = config[property].filter(variant => variant.id == net[property])[0][property]
        }
      }
    }
    return newNetsProperties
  }
 
  let getData = async () => {
    let nets = await fetch(`${apiUrl}/cells/${netType}/${cellId}`)
    nets = await nets.json()
    console.log(nets)
    setNets(nets)
 
    let config = await fetch(`${apiUrl}/config/${netType}`)
    config = await config.json()
    setNetsProperties(getNetsProperties(nets, config))
  }
 
  useEffect(() => {
    getData()
  }, [])
 
  return (
    <>
      <Header/>
      {!(nets && netsProperties) ? <Loader/> :
        <section className={styles.Card}>
          <Slider className={styles.Card__slider} images={[test_img, test_img, test_img]}/>
          <div className={styles.Card__description}>
            <h1>Сетка садовая {netType == 'plastic' ? 'пластиковая' : 'безузелковая'} {cell} мм</h1>
            <CardProperties/>
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias alias veniam labore, sapiente totam ipsum? Eum vero laborum adipisci unde, doloribus natus enim, voluptatibus alias facilis modi fuga laudantium nostrum, doloremque ipsa officiis similique fugiat. Doloremque sequi sit animi eaque asperiores? Hic iure sunt inventore harum error quod quasi dolore?</p>
          </div>
        </section>}
    </>
  )
}
Я не понимаю чем является nets при console.log в функции getData:
JavaScript
1
2
3
4
5
6
7
8
9
10
  let getData = async () => {
    let nets = await fetch(`${apiUrl}/cells/${netType}/${cellId}`)
    nets = await nets.json()
    console.log(nets)
    setNets(nets)
 
    let config = await fetch(`${apiUrl}/config/${netType}`)
    config = await config.json()
    setNetsProperties(getNetsProperties(nets, config))
  }
Мой сервер отдает такой ответ:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[
  {
    "images": [
      "http://localhost:5000/file/6534285779.webp"
    ],
    "id": 1,
    "width": 1,
    "color": 1,
    "quantity": 32,
    "length": 1,
    "price": 29,
    "cell": 1
  },
  {
    "images": [],
    "id": 2,
    "width": 1,
    "color": 2,
    "quantity": 0,
    "length": 2,
    "price": 0,
    "cell": 1
  }
]
Но при console.log выводятся объекты без полей id, images, price и quantity. Я думаю это связанно с функцией getNetsProperties (когда я убирал вызов этой функции, все работало так как я и ожидал):
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  let getNetsProperties = (nets, config) => {
    let newNetsProperties = {}
    for (let net of nets) {
      for (let unnecessaryProperty of ['id', 'images', 'price', 'quantity']) {
        delete net[unnecessaryProperty]
      }
      for (let property of Object.keys(net)) {
        if (newNetsProperties[property]) {
          newNetsProperties[property][net[property]] = config[property].filter(variant => variant.id == net[property])[0][property]
        } else {
          newNetsProperties[property] = {}
          newNetsProperties[property][net[property]] = config[property].filter(variant => variant.id == net[property])[0][property]
        }
      }
    }
    return newNetsProperties
  }
Но эта функция не может изменить переменную ещё до её вызова. Почему так получается объясните пожалуйста. На первый взгляд как будто тут ничего не должно пойти не так, но почему то переменная ведет себя очень странно
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
31.03.2024, 19:34
Ответы с готовыми решениями:

Непонятное поведение поведение TIM6 на STM32f4discovery
Вводные данные: SYSCLK=168Мгц; AHB Pressotir=1; APB1 Pressotir=4; TIM6_Pessotir=3; Т.о. частота тактирования на таймере=42Мгц ...

Непонятное поведение
Всем привет) Задача: выбрать файл и , если это картинка, вывести изображение в окне браузера (причем размер должен быть не более 300px...

Непонятное поведение
Всем привет! В книге &quot;Прата - Язык программирования C++. Лекции и управжения 2011&quot; нашёл вот такой пример: const free_throws...

6
 Аватар для voraa
1259 / 1221 / 180
Регистрация: 21.01.2024
Сообщений: 5,630
31.03.2024, 20:05
Это особенность работы console.log, если выводить объект. Фактически выводится ссылка на объект. И если раскрыть этот объект в консоле, то он будет содержать значения не на момент вывода, а на момент просмотра.
Просто выполните в консоле
JavaScript
1
2
3
let a = {x:1, y:2}
console.log(a)
a.z = 3
и посмотрите объект. Там будет

Code
1
2
3
x: 1
y: 2
z: 3
Добавлено через 3 минуты
https://developer.mozilla.org/... log_static
Code
1
2
3
4
5
Пожалуйста, обратите внимание, что если вы логируете объекты
 в последних версиях Chrome и Firefox, в консоль залогируется не значение объекта,
 а ссылка на него. Это означает, что, возможно, в консоль будет выведено не
 значение объекта на момент вызова console.log(), а будет выведено
 значение объекта на момент открытия консоли.
0
4 / 4 / 1
Регистрация: 26.03.2023
Сообщений: 153
31.03.2024, 21:31  [ТС]
Что значит момент просмотра?
0
 Аватар для voraa
1259 / 1221 / 180
Регистрация: 21.01.2024
Сообщений: 5,630
31.03.2024, 21:39
Цитата Сообщение от samiroutka Посмотреть сообщение
Что значит момент просмотра?
Обычно объект не показывается сразу целиком. Там как правило есть стрелочка, на которую надо нажать, что бы его полностью раскрыть. Вот момент нажатия на эту стрелочку и есть момент просмотра.

Выполнили код (первый скрин)
Нажали на стрелку (второй скрин)
Миниатюры
Непонятное поведение переменной   Непонятное поведение переменной  
0
4 / 4 / 1
Регистрация: 26.03.2023
Сообщений: 153
31.03.2024, 21:43  [ТС]
а есть ли способ нормально просматривать объект (ну или чтобы он сразу раскрывался) на момент вызова console.log?
0
 Аватар для voraa
1259 / 1221 / 180
Регистрация: 21.01.2024
Сообщений: 5,630
31.03.2024, 21:46
Можно в отладчике поставить точку останова на следующий за console.log оператор. И при остановке в отладчике смотреть консоль.
Хотя в отладчике и без console.log все посмотреть можно.
0
4 / 4 / 1
Регистрация: 26.03.2023
Сообщений: 153
01.04.2024, 19:52  [ТС]
да, через отладчик все видно лучше. Но я не понимаю почему мой стейт nets меняется, хотя я даже его не менял (не вызывал лишний раз функцию setNets)

Добавлено через 29 минут
Помоги пожалуйста. Что за магия происходит. Я вообще не меняю state, один раз его устанавливаю через setNets и всё. Но значения меняются. Я нигде его напрямую не меняю, а только передаю в функции. Операторы по типу spread ([...nets]), чтобы нее передавать сам массив, а передавать новый не связанный с ним, тоже не помогают. Помогите

Добавлено через 3 минуты
Извините за лишние эмоции. Нужна была просто ГЛУБОКАЯ копия массива, а не через spread и другие темки. Я использовал JSON parse и stringify
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.04.2024, 19:52
Помогаю со студенческими работами здесь

Непонятное поведение
Касперский обнаружил немного мусора. После загрузки компьютер работает нормально, но со временем начинает подтормаживать. То ли железоЮ то...

Непонятное поведение ОС
Здрасте! Купил новый комп, а он загружается через раз (чаще через несколько раз), выключается долго, и один раз не вышел из спячки. ...

непонятное поведение роутера
Стоит роутер (по схеме модем+wi-fi+свитч) или как оно называется, я хз. Вообщем, моделька ZTE ZXV10 W300 Series. подключение adsl ...

Непонятное поведение STM32F3DISCOVERY
История такая, недавно приобрёл эту плату, первые пару дней все было нормально работала как и должна, но потом вдруг перестал работать...

Непонятное поведение сервлета
Столкнулся с непонятным поведением проги.Есть jsp страница(для входа на сайт) все как обычно, пользователь вводит логин и пароль.Дальше эта...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 09.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru