Почему react не показывает новый массив?

Ссылка скопирована
1 ответ
import { Component } from "react"; import getCharacters from "../getCharacters/getCharacters"; import OneCharacter from "../oneCharacter/oneCharacter"; import Button from "../button/button"; import rightArrow from '../../imgs/right-arrow.png'; import leftArrow from '../../imgs/left-arrow.png'; import './carousel.scss';   function composeCharacters(offset) {     let arr = [];     for (let i = 1; i <= 4; i++) {         arr.push(<OneCharacter offset={offset + i} />);     }     return arr; }   class Carousel extends Component {      state = {         offset: 4,     }     plusChars = () => {             this.setState(({offset}) => ({                 offset: offset + 1             }))     }     minusChars = () => {         if (this.state.offset === 0) {             return;         }         this.setState( ({offset}) => ({             offset: offset - 1         }))     }     onUpdate = () => {         this.setState(({ offset }) => ({             offset: offset + 4,         }))         console.log(this.state.persons);     }     render() {         let arr = [...composeCharacters(this.state.offset)];         console.log(arr);         return (             <section className="carousel">                 <div className="carousel__wrapper">                     <div className="carousel__inner">                         {arr}                     </div>                     <div className="carousel__buttons">                         <div className="carousel__leftA" onClick={this.minusChars}><img src={leftArrow} alt="left arrow" /></div>                         <div className="carousel__rightA" onClick={t<code lang="javascript">  </code>his.plusChars}><img src={rightArrow} alt="right arrow" /></div>                     </div>                 </div>                 <Button name={'Add Hero'} onClick={this.onUpdate} />              </section>         )        }  } export default Carousel;

import { Component } from "react"; import getCharacters from "../getCharacters/getCharacters"; import OneCharacter from "../oneCharacter/oneCharacter"; import Button from "../button/button"; import rightArrow from '../../imgs/right-arrow.png'; import leftArrow from '../../imgs/left-arrow.png'; import './carousel.scss'; function composeCharacters(offset) { let arr = []; for (let i = 1; i <= 4; i++) { arr.push(<OneCharacter offset={offset + i} />); } return arr; } class Carousel extends Component { state = { offset: 4, } plusChars = () => { this.setState(({offset}) => ({ offset: offset + 1 })) } minusChars = () => { if (this.state.offset === 0) { return; } this.setState( ({offset}) => ({ offset: offset - 1 })) } onUpdate = () => { this.setState(({ offset }) => ({ offset: offset + 4, })) console.log(this.state.persons); } render() { let arr = [...composeCharacters(this.state.offset)]; console.log(arr); return ( <section className="carousel"> <div className="carousel__wrapper"> <div className="carousel__inner"> {arr} </div> <div className="carousel__buttons"> <div className="carousel__leftA" onClick={this.minusChars}><img src={leftArrow} alt="left arrow" /></div> <div className="carousel__rightA" onClick={t<code lang="javascript"> </code>his.plusChars}><img src={rightArrow} alt="right arrow" /></div> </div> </div> <Button name={'Add Hero'} onClick={this.onUpdate} /> </section> ) } } export default Carousel;

// Первые четыре элемента показывает нормально, а при нажатии на стрелки меняется offset и arr в render, но на экране всегда только первые четыре элемента. В массиве arr(render) тоже все меняется, я получаю другие элементы с сервера.

Дополнительно:

вопрос оформи нормально, код вставь в тег для кода

  • {Array.from({ length: this.state.offset }).map((_, i) => <OneCharacter key={i} offset={i + 1} />)}

    {Array.from({ length: this.state.offset }).map((_, i) => <OneCharacter key={i} offset={i + 1} />)}

  • szQocks, А почему мой вариант не работает? Ведь state обновляется, arr тоже, следовательно render должен заново пройтись и заменить новый массив на старый?
  • на экране всегда только первые четыре элемента

    for (let i = 1; i <= 4; i++) {

    Действительно, почему же только 4?

  • Suleymanov,
    constructor() {     super();     this.state = {         offset: 4,     }   }

    constructor() { super(); this.state = { offset: 4, } }

    ?

  • WbICHA, szQocks, там i прибавляется к offset. Еще раз пишу в arr который находится в render другие 4 элемента в отличие от тех, которые на экране. При на нажатии на стрелку к offset прибавляется один. Так я хотел динамически подгружать новый элемент и показывать его с тремя прошлыми
  • WbICHA, я тоже кстати это заметил, да и заметил что он обращается к this.state хотя у него просто объявлена глобальная типа переменная которая становится свойством через state = {}

    видимо врёт что у него там что-то работает, каких авторов только не встретишь

  • WbICHA, а хотя нет там 4 будет) но про state я верно написал, не верно объявлен стейт
  • Suleymanov,
    import { Component } from "react"; import getCharacters from "../getCharacters/getCharacters"; import OneCharacter from "../oneCharacter/oneCharacter"; import Button from "../button/button"; import rightArrow from '../../imgs/right-arrow.png'; import leftArrow from '../../imgs/left-arrow.png'; import './carousel.scss';  class Carousel extends Component {  constructor() {     super();     this.state = {         offset: 4,     }   }      plusChars() {             this.setState(({offset}) =&gt; ({                 offset: offset + 1             }))     }     minusChars(){         if (this.state.offset === 0) {             return;         }         this.setState( ({offset}) =&gt; ({             offset: offset - 1         }))     }     onUpdate(){         this.setState(({ offset }) =&gt; ({             offset: offset + 4,         }))         console.log(this.state.persons);     }     render() {         return (             &lt;section className="carousel"&gt;                 &lt;div className="carousel__wrapper"&gt;                     &lt;div className="carousel__inner"&gt;                         {Array.from({ length: this.state.offset }).map((_, i) =&gt; &lt;OneCharacter key={i} offset={i + 1} /&gt;)}                     &lt;/div&gt;                     &lt;div className="carousel__buttons"&gt;                         &lt;div className="carousel__leftA" onClick={this.minusChars}&gt;&lt;img src={leftArrow} alt="left arrow" /&gt;&lt;/div&gt;                         &lt;div className="carousel__rightA" onClick={t&lt;code lang="javascript"&gt;  &lt;/code&gt;his.plusChars}&gt;&lt;img src={rightArrow} alt="right arrow" /&gt;&lt;/div&gt;                     &lt;/div&gt;                 &lt;/div&gt;                 &lt;Button name={'Add Hero'} onClick={this.onUpdate} /&gt;              &lt;/section&gt;         )        }  } export default Carousel;

    import { Component } from "react"; import getCharacters from "../getCharacters/getCharacters"; import OneCharacter from "../oneCharacter/oneCharacter"; import Button from "../button/button"; import rightArrow from '../../imgs/right-arrow.png'; import leftArrow from '../../imgs/left-arrow.png'; import './carousel.scss'; class Carousel extends Component { constructor() { super(); this.state = { offset: 4, } } plusChars() { this.setState(({offset}) =&gt; ({ offset: offset + 1 })) } minusChars(){ if (this.state.offset === 0) { return; } this.setState( ({offset}) =&gt; ({ offset: offset - 1 })) } onUpdate(){ this.setState(({ offset }) =&gt; ({ offset: offset + 4, })) console.log(this.state.persons); } render() { return ( &lt;section className="carousel"&gt; &lt;div className="carousel__wrapper"&gt; &lt;div className="carousel__inner"&gt; {Array.from({ length: this.state.offset }).map((_, i) =&gt; &lt;OneCharacter key={i} offset={i + 1} /&gt;)} &lt;/div&gt; &lt;div className="carousel__buttons"&gt; &lt;div className="carousel__leftA" onClick={this.minusChars}&gt;&lt;img src={leftArrow} alt="left arrow" /&gt;&lt;/div&gt; &lt;div className="carousel__rightA" onClick={t&lt;code lang="javascript"&gt; &lt;/code&gt;his.plusChars}&gt;&lt;img src={rightArrow} alt="right arrow" /&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;Button name={'Add Hero'} onClick={this.onUpdate} /&gt; &lt;/section&gt; ) } } export default Carousel;

    попробуй так

  • szQocks, ваш способ установки state не отличается от моего(лишь небольшими нюансами), ваша строка работает, но не так как я хочу. Ваш вариант создает массив из 4 элементов, а при нажатии на стрелку просто добавляет элемент. Но я все еще хочу понять в чем разница с моим {arr} от {Array.from({ length: this.state.offset }).map((_, i) => )} ведь и там и там массив из компонентов?
  • Suleymanov, особо ничем не отличается отрисовка, просто в твоём случае у них нет ключей

    я просто предложил запись короче, это не решение к вопросу, так просто от скуки написал

    результат тот который нужен или нет ? или всё ещё не так работает ?

  • szQocks, А в ключах может быть проблема?
  • Suleymanov,

    ключи нужны что бы реакт понимал где какой компонент обновился в виртуальном доме, возможно и в ключах проблема, вот только есть ещё одна проблема, из вопроса - я не понял в чём проблема вахах)

  • szQocks, спасибо зато я кажется я все понял
  • Suleymanov, по факту эти компоненты должны пересоздаваться и перерисовываться, даже если и ключи не указаны, так как при любом изменении стейт - создаётся новый массив

    скорее ошибка была в том - как был объявлен стейт, видимо из-за кривого объявления, компонент не перерисовывался - ну это мои догадки, я на классовых не пишу поэтому уже и не помню что там да как

  • Suleymanov, ты можешь сказать, щас работает так как надо или нет ? и если работает так как надо - ответь сам на свой вопрос, и сделай ответ решением
  • Все нашел я просто добавил key в функцию

    function composeCharacters(offset) {     let arr = [];     for (let i = 1; i &lt;= 4; i++) {         arr.push(&lt;OneCharacter offset={offset + i} key={offset+i} /&gt;);     }     return arr; }

    function composeCharacters(offset) { let arr = []; for (let i = 1; i &lt;= 4; i++) { arr.push(&lt;OneCharacter offset={offset + i} key={offset+i} /&gt;); } return arr; }

    И все заработало, видимо react не понимал какие объекты изменились

    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Мария Код Ответ

    React не обновляет компоненты, когда новый массив присваивается напрямую, потому что он сравнивает ссылки на объекты, а не их содержимое. Если вы обновляете массив, то React не заметит изменений, так как ссылка на массив остается той же самой.

    Для того чтобы заставить React обновить компоненты при изменении массива, вы можете использовать метод `setState` для установки нового состояния. Например, если у вас есть массив `myArray` и вы хотите обновить его, вместо того чтобы делать `this.state.myArray = newArray`, сделайте следующее:

    ```html

    this.setState({ myArray: newArray });

    this.setState({ myArray: newArray });

    ```

    Это позволит React обнаружить изменение и обновить компоненты с новым массивом.

    Также убедитесь, что вы не мутируете существующий массив напрямую, так как это также может привести к проблемам с обновлением компонентов. Вместо этого создавайте новый массив на основе старого, если необходимо внести изменения.

    Например, вместо этого:

    ```html

    this.state.myArray.push(newElement);
    this.setState({ myArray: this.state.myArray });

    this.state.myArray.push(newElement); this.setState({ myArray: this.state.myArray });

    ```

    Лучше сделать так:

    ```html

    const newArray = [...this.state.myArray, newElement];
    this.setState({ myArray: newArray });

    const newArray = [...this.state.myArray, newElement]; this.setState({ myArray: newArray });

    ```

    Таким образом, React сможет правильно обнаруживать изменения в массиве и обновлять компоненты соответствующим образом.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно