Государство не всегда обновляет - PullRequest
0 голосов
/ 08 июля 2019

Переменные выбора в useState не всегда обновляются.В приведенном ниже коде я показываю файл контекста и компонент выбора.Файл контекста содержит глобальное состояние для моего приложения реагирования, а компоненту выбора передается метод setChoices для обновления состояния в GameContext.Предполагается, что мой метод setChoices обновляет значение каждого выбора, но состояние обновляется только случайным образом, а не каждый раз.

//GameContext file
import React, { createContext, useState } from 'react';

export const GameContext = createContext();

const GameContextProvider = props => {
    const [gameItems, setGameItems] = useState({
        user: {choice: null, score: 0},
        cpu: {choice: null, score: 0}
    })

    const setChoices = (userChoice, cpuChoice) => {
        setGameItems({
            ...gameItems, 
            user:{...gameItems.user, choice: userChoice},
            cpu: {...gameItems.cpu, choice: cpuChoice}
        });  
    }

    const cpuScore = () => {
      setGameItems({
         ...gameItems, 
         cpu:{...gameItems.cpu, score: gameItems.cpu.score + 1}
      })



 return (
        <GameContext.Provider value={{gameItems, setChoices}}>
            { props.children }
        </GameContext.Provider>
    )
}

//choices component
import React, { useContext } from 'react';
import { GameContext } from '../contexts/GameContext';

const Choices = (props) => {

    const {  setChoices } = useContext(GameContext);

    const getCpuChoice = () => {
        const cpuChoices = ['r', 'p', 's'];
        const randomIndex = Math.floor((Math.random() * 3));
        const cpuDecision = cpuChoices[randomIndex];
        return cpuDecision
    }

    const playGame = (e) => {
        const userChoice = e.target.id;
        const cpuChoice = getCpuChoice();

        setChoices(userChoice, cpuChoice);
        cpuScore();
    } 

    return (
            <div>
                <h1>Make Your Selection</h1>
                <div className="choices">
                    <i className="choice fas fa-hand-paper fa-10x" id="p" onClick={playGame}></i>
                    <i className="choice fas fa-hand-rock fa-10x" id="r" onClick={playGame}></i>
                    <i className="choice fas fa-hand-scissors fa-10x" id='s' onClick={playGame}></i>
                </div>
            </div>
        )
    }

Я ожидаю, что свойство выбора для пользователя и процессора будет обновляться каждый раз при вызове setChoices.Что-то не так с тем, как я обновляю состояние?

Ответы [ 2 ]

0 голосов
/ 08 июля 2019

Чтение: https://www.freecodecamp.org/news/get-pro-with-react-setstate-in-10-minutes-d38251d1c781/

Неглубокое сравнение объектов вызывает такое поведение.

0 голосов
/ 08 июля 2019

Я сделал небольшую настройку, чтобы попытаться эмулировать https://codesandbox.io/s/festive-almeida-4zx3c

То, что не всегда обновляется, может создать впечатление, что иногда вы получаете одинаковые значения из-за этого randomIndex

Если значение вывода совпадает с предыдущим, оно не будет обновляться. Будет думать, что состояние не изменилось.

Решения:

Сделать принудительное обновление: Как заставить компонент повторно выполнить рендеринг с перехватами в React?

Или добавить внутреннее значение в состояние, что-то, что всегда изменяется, что-то вроде хеша.

...