【问题标题】:How to pass State in Context React如何在上下文 React 中传递状态
【发布时间】:2021-10-02 19:59:59
【问题描述】:

我正在尝试使用useContext 传递和更新状态;

App.js

import Home from './components/Home'
const UserContext = createContext();

function App() {
  const [name, setName] = useState('Name');

  return (
      <UserContext.Provider value={{name, setName}}>
        <Home/>
      </UserContext.Provider>
  );
}

export default App;

Home.js

import UserContext from '../../App'

function Home() {
    const user = useContext(UserContext);

    return (
        <>
        <label>Your name:</label>
        <input type='text' onChange={e => user.setName(e.target.value)} />
        <p>{user.name}</p>
        </>
    )
}

export default Home;

我收到这个错误

TypeError: Cannot read properties of undefined (reading 'name');

如何使用useContext在组件之间传递状态的正确方法是什么?

【问题讨论】:

  • 您发布的代码与您收到的错误不符。首先,它不会编译,因为您不导出UserContext。这意味着您不能将其导入到您的 Home 组件中。一旦你这样做了,你的应用程序就可以工作了。我已将您的代码复制粘贴到 Create-react-app 中,它可以工作。
  • 如何导出上下文?

标签: javascript reactjs use-context


【解决方案1】:

1.为动态上下文设置父状态

首先,为了有一个可以传递给消费者的动态上下文,我将使用父母的状态。这确保了我有一个单一的事实来源。例如,我的父 App 将如下所示:

const App = () => {
  const [name, setName] = useState("John");
  const value = { name, setName };

  return (
   ...
  );
};

名称存储在状态中。稍后我们将通过上下文传递 name 和 setter 函数 setName

2。创建上下文

接下来,我创建了一个像这样的 name 上下文:

// set the defaults
const NameContext = React.createContext({
  name: "John",
  setName: () => {}
});

在这里,我设置了 name ('John') 和 setName 函数的默认值,该函数将由上下文提供者发送给消费者。这些只是默认值,我将在父 App 中使用提供程序组件时提供它们的值。

3.创建上下文消费者

为了让名称切换器设置名称并显示,它应该可以通过上下文访问名称设置器功能。它可能看起来像这样:

const NameSwitcher = () => {
const { name, setName } = useContext(NameContext);
 return (
    <label>Your name:</label><br />
    <input type='text' onChange={e => setName(e.target.value)} />
    <p>{name}</p>
  );
};

这里我只是将 name 设置为输入值,但您可能有自己的逻辑来为此设置名称。

4.将消费者包装在提供者中

现在我将在 NameContext.Provider 中呈现我的名称切换器组件,并将必须通过上下文发送到更深层次的值传递。这是我的父应用程序的外观:

const App = () => {
   const [name, setName] = useState("John");
   const value = { name, setName };

   return (
    <Name.Provider value={value}>
      <NameSwitcher />
    </Name.Provider>
   );
};

【讨论】:

    【解决方案2】:

    你需要导出你的UserContext,以便在需要它的组件中导入:

    export const UserContext = React.createContext();
    
    function App() {
      const [name, setName] = useState('Name');
    
      return (
        <UserContext.Provider value={{ name, setName }}>
          <Home />
        </UserContext.Provider>
      );
    }
    

    之后你可以在你的 App 组件中导入它:

    import { UserContext } '../../App'
    
    function Home() {
        const user = useContext(UserContext);
    
        return (
            <>
                <label>Your name:</label>
                <input type='text' onChange={e => user.setName(e.target.value)} />
                <p>{user.name}</p>
            </>
        )
    }
    

    【讨论】:

    • 我不知道,谢谢
    • 如果您需要一个文件中的变量,并且没有使用constletvar 在该文件中定义它 - 您需要导入它。如果您需要导入它,则必须将其导出到其他文件中。
    • 我认为&lt;.Provider&gt; 正在以某种方式将其导出给所有孩子
    猜你喜欢
    • 1970-01-01
    • 2018-10-22
    • 1970-01-01
    • 2020-08-29
    • 2022-01-22
    • 2021-07-31
    • 2017-04-04
    • 2023-03-05
    • 2017-05-18
    相关资源
    最近更新 更多