React не refre sh после обновления состояния (массив объектов) - PullRequest
0 голосов
/ 11 февраля 2020

Я показываю cards с функцией отображения моего состояния. Состояние выглядит следующим образом:

[{ position: "0", state: "pending" }, 
{ position: "1", state: "pending" }, 
{ position: "2", state: "pending" }]

В функции я меняю «состояние» с «в ожидании» на «вправо», но оно ничего не обновляет sh на странице.

export const Card: React.FC<ICardOwnProps> = ({ }) => {
    const [rollingCards, setRollingCards] = useState<IRollingCard[]>([{ position: "0", state: "pending" }, { position: "1", state: "pending" }, { position: "2", state: "pending" }])

    const handleClick = () => {
        let newArray = rollingCards;
        newArray.splice(0, 1)
        setRollingCards(newArray);
    }

    useEffect(() => { console.log("wtf") })

    return (
        <StyledCard className="Card">
            {rollingCards.map((v, i, a) =>
                <Container key={i} className={"position" + v.position} >{v.state}</Container>
            )}
            <div className="card__container--button">
                <button onClick={handleClick}>Oui</button>
                <button>Non</button>
                {rollingCards[0].state}
           </div>
        </StyledCard>
    );
}

С этого момента ничего не меняется, но когда я добавляю новый элемент состояния, который я обновляю одновременно с RollingCards, он обновляется. Я добавил счетчик, и с этим он обновляет страницу.

(я также пытался соединить массив, чтобы увидеть, обновится ли React, но не сделал)

Любая идея, почему я ' У тебя странное поведение?

Спасибо.

Ответы [ 2 ]

1 голос
/ 11 февраля 2020

Это связано с тем, что при принятии решения о повторном рендеринге React выполняет сравнение ссылочного равенства реквизита / состояния.

newArray имеет ту же ссылку, что и rollCards, из-за чего функциональный компонент не рендерится на setRollingCards

Изменить

setRollingCards(newArray)

на

setRollingCards([...newArray])

Это создаст новый массив (новую ссылку) с элементами из newArray

Рабочее решение: https://codesandbox.io/s/admiring-wave-9kgqq

1 голос
/ 11 февраля 2020

Поскольку реагирование использует Object.is, чтобы определить, изменилось ли состояние.

В вашем коде newArray является той же ссылкой, что и rollingCards, вы можете использовать Object.is(newArray, rollingCards) для проверки.

const handleClick = () => {
    let newArray = rollingCards;
    newArray.splice(0, 1)   // Object.is(newArray, rollingCards) is true
    setRollingCards(newArray);
}

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

setRollingCards(rollingCards.filter((item, index) => index !== 0);

Не только этот метод, если это другой справочник

...