如何通过反应上下文 api 传递多个状态

ano*_*ran 7 javascript state reactjs

我正在创建一个反应游戏应用程序,我想在多个组件之间传递状态。为此,我第一次尝试使用 react context api。所以这是我的 GameContext.js

import React, { useState, createContext } from 'react';

const GameContext = createContext();

const GameProvider = ({ children }) => {
  const [name, setName] = useState('');
  const [color, setColor] = useState('');
  const [startgame, setStartgame] = useState(false);


  return (
    <GameContext.Provider value={[name, setName]}>
      {children}
    </GameContext.Provider>
  );
};

export { GameContext, GameProvider };
Run Code Online (Sandbox Code Playgroud)

我可以name在子组件中使用

import { GameContext } from '../../context/GameContext';    
const [name, setName] = useContext(GameContext);
console.log(name);
Run Code Online (Sandbox Code Playgroud)

但是现在我想将其他状态值从 GameContext.js获取到同一个子组件中,例如[color, setColor][startgame, setStartgame]
如何将这些值放入子组件中?

我还有一个问题,不知怎的,我觉得这是一个非常愚蠢的问题,但为什么我不能在 GameContext.js 中做这样的事情?...

<GameContext.Provider value={[name, setName,color, setColor, startgame, setStartgame]}>
Run Code Online (Sandbox Code Playgroud)

并像这样获取子组件中的值...

const [name, setName,color, setColor, startgame, setStartgame] = useContext(GameContext);
Run Code Online (Sandbox Code Playgroud)

我试过这个,但浏览器抱怨我违反了反应钩子的规则。

Zoh*_*aib 23

Provider 接受传递任何值,因此您可以在此处 paas 对象并将您的值作为属性。

<GameContext.Provider
 value={{ name: [name, setName], color: [color, setColor] }}
   >
  {props.children}
</GameContext.Provider>;
Run Code Online (Sandbox Code Playgroud)

以及您在 Child 中访问的位置

 const { name, color } = React.useContext(GameContext);
 const [nameValue, setnameValue] = name;
 const [colorValue, setcolorValue] = color;
Run Code Online (Sandbox Code Playgroud)

  • 第二段代码中的 MyContext 不应该是 GameContext 吗? (2认同)

Fra*_*ion 9

useReducer更适合您的情况:

import React, { useState, useReducer, createContext } from 'react';

const initialState = {
  name: '',
  color: '',
  startgame: false
}

function reducer(state, action) {
  return { ...state, ...action };
}

const GameContext = createContext();

const GameProvider = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <GameContext.Provider value={{ state, dispatch }}>
      {children}
    </GameContext.Provider>
  );
};

export { GameContext, GameProvider };
Run Code Online (Sandbox Code Playgroud)

子组件:

import { GameContext } from '../../context/GameContext'; 

...

const { state: { name, color }, dispatch } = useContext(GameContext);
console.log(name);
console.log(color);

// event handler
const handleChangeName = (event) => {
  dispatch({ name: event.target.value });
}

const handleChangeColor = (event) => {
  dispatch({ color: event.target.value });
}
Run Code Online (Sandbox Code Playgroud)