上下文更改后 ReactJS 不重新渲染
ReactJS not re-rendering after context changed
我这里有一个基本应用程序,我正在尝试正确配置 React Context,但它无法正常工作。我的目标是在 React 上下文中使用 currentStage 的内容呈现 PlayScreen。 Game 更改上下文,但 App 继续使用“welcome”字符串而不是“won”呈现 PlayScreen ”或“丢失”。
此外,我知道 gameContext.js 用于自动完成,但我在那里添加了“欢迎”以获得第一个默认状态。当 App 首次呈现时,我无法找到设置第一个“欢迎”上下文的方法。
我尝试用上下文本身喂 PlayScreen 但没有用,现在我尝试用它设置状态但它也不起作用(即使使用 useEffect并将上下文作为依赖项)。
所以我有两个问题,我做错了什么?而且,我设置“欢迎”默认状态的方式是错误的?如果是这样,我该怎么做?谢谢。
gameContext.js
import React from 'react';
const GameContext = React.createContext({
currentStage: 'welcome',
playerStage: (stage) => {},
});
export default GameContext;
GameProvider.jsx
import React, { useReducer, useMemo } from 'react';
import PropTypes from 'prop-types';
import GameContext from './gameContext';
const defaultState = {
currentStage: '',
};
const gameReducer = (state, action) => {
if (action.type === 'STAGE') {
return {
currentStage: action.playerStage,
};
}
return defaultState;
};
const GameProvider = ({ children }) => {
const [gameState, dispatchGameAction] = useReducer(gameReducer, defaultState);
const playerStageHandler = (playerStage) => {
dispatchGameAction({
type: 'STAGE',
playerStage,
});
};
const gameContext = useMemo(
() => ({
currentStage: gameState.currentStage,
playerStage: playerStageHandler,
}),
[gameState.currentStage]
);
return (
<GameContext.Provider value={gameContext}>{children}</GameContext.Provider>
);
};
GameProvider.propTypes = {
children: PropTypes.node.isRequired,
};
export default GameProvider;
App.jsx
import React, { useContext, useState, useEffect } from 'react';
import GameProvider from './store/GameProvider';
import GameContext from './store/gameContext';
import PlayScreen from './components/PlayScreen';
import Settings from './components/Settings';
import Game from './components/Game';
const App = () => {
const gameContext = useContext(GameContext);
const [stage, setStage] = useState(gameContext.currentStage);
useEffect(() => {
setStage(gameContext.currentStage);
}, [gameContext]);
const [currentScreen, setCurrentScreen] = useState({
playScreen: true,
settings: false,
game: false,
});
const changeScreenHandler = (newScreen) => {
switch (newScreen) {
case 'playScreen':
setCurrentScreen({
playScreen: true,
settings: false,
game: false,
});
break;
case 'settings':
setCurrentScreen({
playScreen: false,
settings: true,
game: false,
});
break;
case 'game':
setCurrentScreen({
playScreen: false,
settings: false,
game: true,
});
break;
default:
break;
}
};
return (
<GameProvider>
{currentScreen.playScreen && (
<PlayScreen stage={stage} onChangeScreen={changeScreenHandler} />
)}
{currentScreen.settings && (
<Settings onChangeScreen={changeScreenHandler} />
)}
{currentScreen.game && <Game onChangeScreen={changeScreenHandler} />}
</GameProvider>
);
};
export default App;
PlayScreen.jsx
import PropTypes from 'prop-types';
const PlayScreen = ({ stage, onChangeScreen }) => {
const clickHandler = () => {
onChangeScreen('settings');
};
return (
<div>
<h1>{stage}</h1>
<button type="button" onClick={clickHandler}>
Go
</button>
</div>
);
};
PlayScreen.propTypes = {
stage: PropTypes.string.isRequired,
onChangeScreen: PropTypes.func.isRequired,
};
export default PlayScreen;
Game.jsx
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import GameContext from '../store/gameContext';
const Game = ({ onChangeScreen }) => {
const gameContext = useContext(GameContext);
const wonHandler = () => {
onChangeScreen('playScreen');
gameContext.playerStage('won');
};
const lostHandler = () => {
onChangeScreen('playScreen');
gameContext.playerStage('lost');
};
return (
<div>
<h1>GAME RUNNING</h1>
<button type="button" onClick={wonHandler}>
won
</button>
<button type="button" onClick={lostHandler}>
lost
</button>
</div>
);
};
Game.propTypes = {
onChangeScreen: PropTypes.func.isRequired,
};
export default Game;
您正在使用 GameProvider 之上的 GameContext。上下文不应该可用,因为 GameProvider 未向 App 提供上下文。
尝试将 GameProvider 下的所有内容移动到它自己的组件中并在那里使用上下文。
我这里有一个基本应用程序,我正在尝试正确配置 React Context,但它无法正常工作。我的目标是在 React 上下文中使用 currentStage 的内容呈现 PlayScreen。 Game 更改上下文,但 App 继续使用“welcome”字符串而不是“won”呈现 PlayScreen ”或“丢失”。
此外,我知道 gameContext.js 用于自动完成,但我在那里添加了“欢迎”以获得第一个默认状态。当 App 首次呈现时,我无法找到设置第一个“欢迎”上下文的方法。
我尝试用上下文本身喂 PlayScreen 但没有用,现在我尝试用它设置状态但它也不起作用(即使使用 useEffect并将上下文作为依赖项)。
所以我有两个问题,我做错了什么?而且,我设置“欢迎”默认状态的方式是错误的?如果是这样,我该怎么做?谢谢。
gameContext.js
import React from 'react';
const GameContext = React.createContext({
currentStage: 'welcome',
playerStage: (stage) => {},
});
export default GameContext;
GameProvider.jsx
import React, { useReducer, useMemo } from 'react';
import PropTypes from 'prop-types';
import GameContext from './gameContext';
const defaultState = {
currentStage: '',
};
const gameReducer = (state, action) => {
if (action.type === 'STAGE') {
return {
currentStage: action.playerStage,
};
}
return defaultState;
};
const GameProvider = ({ children }) => {
const [gameState, dispatchGameAction] = useReducer(gameReducer, defaultState);
const playerStageHandler = (playerStage) => {
dispatchGameAction({
type: 'STAGE',
playerStage,
});
};
const gameContext = useMemo(
() => ({
currentStage: gameState.currentStage,
playerStage: playerStageHandler,
}),
[gameState.currentStage]
);
return (
<GameContext.Provider value={gameContext}>{children}</GameContext.Provider>
);
};
GameProvider.propTypes = {
children: PropTypes.node.isRequired,
};
export default GameProvider;
App.jsx
import React, { useContext, useState, useEffect } from 'react';
import GameProvider from './store/GameProvider';
import GameContext from './store/gameContext';
import PlayScreen from './components/PlayScreen';
import Settings from './components/Settings';
import Game from './components/Game';
const App = () => {
const gameContext = useContext(GameContext);
const [stage, setStage] = useState(gameContext.currentStage);
useEffect(() => {
setStage(gameContext.currentStage);
}, [gameContext]);
const [currentScreen, setCurrentScreen] = useState({
playScreen: true,
settings: false,
game: false,
});
const changeScreenHandler = (newScreen) => {
switch (newScreen) {
case 'playScreen':
setCurrentScreen({
playScreen: true,
settings: false,
game: false,
});
break;
case 'settings':
setCurrentScreen({
playScreen: false,
settings: true,
game: false,
});
break;
case 'game':
setCurrentScreen({
playScreen: false,
settings: false,
game: true,
});
break;
default:
break;
}
};
return (
<GameProvider>
{currentScreen.playScreen && (
<PlayScreen stage={stage} onChangeScreen={changeScreenHandler} />
)}
{currentScreen.settings && (
<Settings onChangeScreen={changeScreenHandler} />
)}
{currentScreen.game && <Game onChangeScreen={changeScreenHandler} />}
</GameProvider>
);
};
export default App;
PlayScreen.jsx
import PropTypes from 'prop-types';
const PlayScreen = ({ stage, onChangeScreen }) => {
const clickHandler = () => {
onChangeScreen('settings');
};
return (
<div>
<h1>{stage}</h1>
<button type="button" onClick={clickHandler}>
Go
</button>
</div>
);
};
PlayScreen.propTypes = {
stage: PropTypes.string.isRequired,
onChangeScreen: PropTypes.func.isRequired,
};
export default PlayScreen;
Game.jsx
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import GameContext from '../store/gameContext';
const Game = ({ onChangeScreen }) => {
const gameContext = useContext(GameContext);
const wonHandler = () => {
onChangeScreen('playScreen');
gameContext.playerStage('won');
};
const lostHandler = () => {
onChangeScreen('playScreen');
gameContext.playerStage('lost');
};
return (
<div>
<h1>GAME RUNNING</h1>
<button type="button" onClick={wonHandler}>
won
</button>
<button type="button" onClick={lostHandler}>
lost
</button>
</div>
);
};
Game.propTypes = {
onChangeScreen: PropTypes.func.isRequired,
};
export default Game;
您正在使用 GameProvider 之上的 GameContext。上下文不应该可用,因为 GameProvider 未向 App 提供上下文。
尝试将 GameProvider 下的所有内容移动到它自己的组件中并在那里使用上下文。