Почему react не показывает новый массив?
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} />)}
на экране всегда только первые четыре элемента
for (let i = 1; i <= 4; i++) {
Действительно, почему же только 4?
constructor() { super(); this.state = { offset: 4, } } |
constructor() { super(); this.state = { offset: 4, } }
?
видимо врёт что у него там что-то работает, каких авторов только не встретишь
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}) => ({ 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() { return ( <section className="carousel"> <div className="carousel__wrapper"> <div className="carousel__inner"> {Array.from({ length: this.state.offset }).map((_, i) => <OneCharacter key={i} offset={i + 1} />)} </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'; class Carousel extends Component { constructor() { super(); this.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() { return ( <section className="carousel"> <div className="carousel__wrapper"> <div className="carousel__inner"> {Array.from({ length: this.state.offset }).map((_, i) => <OneCharacter key={i} offset={i + 1} />)} </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;
попробуй так
я просто предложил запись короче, это не решение к вопросу, так просто от скуки написал
результат тот который нужен или нет ? или всё ещё не так работает ?
ключи нужны что бы реакт понимал где какой компонент обновился в виртуальном доме, возможно и в ключах проблема, вот только есть ещё одна проблема, из вопроса - я не понял в чём проблема вахах)
скорее ошибка была в том - как был объявлен стейт, видимо из-за кривого объявления, компонент не перерисовывался - ну это мои догадки, я на классовых не пишу поэтому уже и не помню что там да как
Все нашел я просто добавил key в функцию
function composeCharacters(offset) { let arr = []; for (let i = 1; i <= 4; i++) { arr.push(<OneCharacter offset={offset + i} key={offset+i} />); } return arr; } |
function composeCharacters(offset) { let arr = []; for (let i = 1; i <= 4; i++) { arr.push(<OneCharacter offset={offset + i} key={offset+i} />); } return arr; }
И все заработало, видимо react не понимал какие объекты изменились
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
React не обновляет компоненты, когда новый массив присваивается напрямую, потому что он сравнивает ссылки на объекты, а не их содержимое. Если вы обновляете массив, то React не заметит изменений, так как ссылка на массив остается той же самой.
Для того чтобы заставить React обновить компоненты при изменении массива, вы можете использовать метод `setState` для установки нового состояния. Например, если у вас есть массив `myArray` и вы хотите обновить его, вместо того чтобы делать `this.state.myArray = newArray`, сделайте следующее:
```html
this.setState({ myArray: newArray });
```
Это позволит React обнаружить изменение и обновить компоненты с новым массивом.
Также убедитесь, что вы не мутируете существующий массив напрямую, так как это также может привести к проблемам с обновлением компонентов. Вместо этого создавайте новый массив на основе старого, если необходимо внести изменения.
Например, вместо этого:
```html
this.state.myArray.push(newElement); this.setState({ myArray: this.state.myArray });
```
Лучше сделать так:
```html
const newArray = [...this.state.myArray, newElement]; this.setState({ myArray: newArray });
```
Таким образом, React сможет правильно обнаруживать изменения в массиве и обновлять компоненты соответствующим образом.