Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 如何使用React-useContext钩子来控制应用程序和条件呈现?_Reactjs_React Hooks_React Context - Fatal编程技术网

Reactjs 如何使用React-useContext钩子来控制应用程序和条件呈现?

Reactjs 如何使用React-useContext钩子来控制应用程序和条件呈现?,reactjs,react-hooks,react-context,Reactjs,React Hooks,React Context,我第一次尝试使用React钩子,我希望最终替换旧的上下文API。如何实现useContext钩子来实现全局状态 我一直在努力学习一些关于中级、其他堆栈溢出帖子和一些随机博客帖子的教程。以下是我目前拥有的代码: APP.JS import React from 'react'; import { AppProvider, useAppValue } from './AppContext'; import FormLogin from './FormLogin'; import FormRegist

我第一次尝试使用React钩子,我希望最终替换旧的上下文API。如何实现useContext钩子来实现全局状态

我一直在努力学习一些关于中级、其他堆栈溢出帖子和一些随机博客帖子的教程。以下是我目前拥有的代码:

APP.JS

import React from 'react';
import { AppProvider, useAppValue } from './AppContext';
import FormLogin from './FormLogin';
import FormRegister from './FormRegister';

const App = () => {
  const initialState = {
    page: <FormLogin/>
  }

  const reducer = (state, action) => {
    switch (action.type) {
      case 'loadLogin':
        return {
          ...state,
          page: <FormLogin/>
        };
      case 'loadRegister':
        return {
          ...state,
          page: <FormRegister/>
        };
      default:
        return state;
    }
  };

  let { page } = useAppValue();
  let currentPage = page ? page : <FormLogin/>

  return (
    <AppProvider initialState={initialState} reducer={reducer}>
      <div className="App">
        {currentPage}
      </div>
    </AppProvider>    
  );
}

export default App;
从“React”导入React;
从“/AppContext”导入{AppProvider,useAppValue};
从“/FormLogin”导入FormLogin;
从“/FormRegister”导入FormRegister;
常量应用=()=>{
常量初始状态={
第页:
}
const reducer=(状态、操作)=>{
开关(动作类型){
案例“loadLogin”:
返回{
状态
第页:
};
“装入寄存器”案例:
返回{
状态
第页:
};
违约:
返回状态;
}
};
设{page}=useAppValue();
让currentPage=第页?第页:
返回(
{currentPage}
);
}
导出默认应用程序;
APPCONTEXT.JS

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

export const AppContext = createContext();
export const AppProvider = ({reducer, initialState, children}) => (
  <AppContext.Provider value={useReducer(reducer, initialState)}>
    {children}
  </AppContext.Provider>
);

export const useAppValue = () => useContext(AppContext);
import React,{createContext,useContext,useReducer}来自“React”;
export const AppContext=createContext();
export const AppProvider=({reducer,initialState,children})=>(
{儿童}
);
export const useAppValue=()=>useContext(AppContext);
这两个表单组件基本上是虚拟组件,其中JSX最少

我不断收到多个“类型错误:无法读取未定义的”错误的属性“页面”。这是使用新的useContext钩子的错误方法吗


理想情况下,我希望每个表单都有一个链接,当单击该链接时,可以将您更改为另一个表单。i、 e.如果您在登录表单上,但需要注册,则会更改为注册表单;如果您在注册表单上,但已经拥有帐户,则会将您转到登录表单。

首先,您没有正确使用useContext钩子的Reducer逻辑。您必须首先了解,除非层次结构中有提供程序,否则将无法使用上下文。由于AppProvider是在应用程序内呈现的,所以您无法在应用程序内使用上下文

其次,不能将组件作为标记存储在reducer中,如果需要,可以存储其引用

因此,您的代码最终看起来像

import React from 'react';
import { AppProvider, useAppValue } from './AppContext';
import FormLogin from './FormLogin';
import FormRegister from './FormRegister';

  const initialState = {
    page: FormLogin
  }

  const reducer = (state, action) => {
    switch (action.type) {
      case 'loadLogin':
        return {
          ...state,
          page: FormLogin
        };
      case 'loadRegister':
        return {
          ...state,
          page: FormRegister
        };
      default:
        return state;
    }
  };

const App = () => {
  let [{ page: Page }] = useAppValue();

  return (

      <div className="App">
         <Page />
      </div>
  );
}

export default (props) => (
      <AppProvider initialState={initialState} reducer={reducer}>
          <App {...props} />
      </AppProvider>
)
从“React”导入React;
从“/AppContext”导入{AppProvider,useAppValue};
从“/FormLogin”导入FormLogin;
从“/FormRegister”导入FormRegister;
常量初始状态={
页面:FormLogin
}
const reducer=(状态、操作)=>{
开关(动作类型){
案例“loadLogin”:
返回{
状态
页面:FormLogin
};
“装入寄存器”案例:
返回{
状态
页码:FormRegister
};
违约:
返回状态;
}
};
常量应用=()=>{
让[{page:page}]=useAppValue();
返回(
);
}
导出默认值(道具)=>(
)

编辑:确保在页面解构周围添加数组。

首先,您没有正确使用useContext钩子的Reducer逻辑。您必须首先了解,除非层次结构中有提供程序,否则将无法使用上下文。由于AppProvider是在应用程序内呈现的,所以您无法在应用程序内使用上下文

其次,不能将组件作为标记存储在reducer中,如果需要,可以存储其引用

因此,您的代码最终看起来像

import React from 'react';
import { AppProvider, useAppValue } from './AppContext';
import FormLogin from './FormLogin';
import FormRegister from './FormRegister';

  const initialState = {
    page: FormLogin
  }

  const reducer = (state, action) => {
    switch (action.type) {
      case 'loadLogin':
        return {
          ...state,
          page: FormLogin
        };
      case 'loadRegister':
        return {
          ...state,
          page: FormRegister
        };
      default:
        return state;
    }
  };

const App = () => {
  let [{ page: Page }] = useAppValue();

  return (

      <div className="App">
         <Page />
      </div>
  );
}

export default (props) => (
      <AppProvider initialState={initialState} reducer={reducer}>
          <App {...props} />
      </AppProvider>
)
从“React”导入React;
从“/AppContext”导入{AppProvider,useAppValue};
从“/FormLogin”导入FormLogin;
从“/FormRegister”导入FormRegister;
常量初始状态={
页面:FormLogin
}
const reducer=(状态、操作)=>{
开关(动作类型){
案例“loadLogin”:
返回{
状态
页面:FormLogin
};
“装入寄存器”案例:
返回{
状态
页码:FormRegister
};
违约:
返回状态;
}
};
常量应用=()=>{
让[{page:page}]=useAppValue();
返回(
);
}
导出默认值(道具)=>(
)

编辑:确保在页面解构周围添加数组。

使用useContext是错误的。在useContext的层次结构中没有任何提供程序

这是我已经实现的使用减缩器的示例方法

在Store.js中,要初始化React上下文-

import {createContext} from 'react';
const Context = createContext();
export default Context;
在Reducers.js中,具有公共状态管理系统的逻辑

import React, {useReducer} from 'react';
import Context from './Store';

const initialState = {
 count: 0,
 someothervalue: 'hello'
}

function reducer(state, action) {
 const {count, ...otherValues} = state;
 switch(action.type) {
    case 'increment':
        return {count: count + 1, ...otherValues};
    case 'decrement':
        return (count > 0) ? {count: count - 1, ...otherValues} : state;
    default:
        return state;
 }
}

const ReducerProvider = (props) => {
 const [state, dispatch] = useReducer(reducer, initialState);
 return (<Context.Provider value={{state, dispatch}}>
    {props.children}
 </Context.Provider>)
}

export default ReducerProvider;

使用useContext是错误的。在useContext的层次结构中没有任何提供程序

这是我已经实现的使用减缩器的示例方法

在Store.js中,要初始化React上下文-

import {createContext} from 'react';
const Context = createContext();
export default Context;
在Reducers.js中,具有公共状态管理系统的逻辑

import React, {useReducer} from 'react';
import Context from './Store';

const initialState = {
 count: 0,
 someothervalue: 'hello'
}

function reducer(state, action) {
 const {count, ...otherValues} = state;
 switch(action.type) {
    case 'increment':
        return {count: count + 1, ...otherValues};
    case 'decrement':
        return (count > 0) ? {count: count - 1, ...otherValues} : state;
    default:
        return state;
 }
}

const ReducerProvider = (props) => {
 const [state, dispatch] = useReducer(reducer, initialState);
 return (<Context.Provider value={{state, dispatch}}>
    {props.children}
 </Context.Provider>)
}

export default ReducerProvider;

我试图实现这一点,正如你在这里所说的:,但它似乎不起作用。您的标记没有定义。@smkarber,这是我这边的一个小错误,应该是
let{page:page}=useAppValue()谢谢更新。它有一个新的错误,我会继续努力找出问题所在,看看我是否能让它正常工作。它还是不喜欢这个。错误为:“警告:React.createElement:type无效--需要字符串(对于内置组件)或类/函数(对于复合组件),但得到:undefined。您可能忘记了从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。”再次抱歉此错误,我也错过了reducer部分,它应该是
return{…state,page:FormLogin}检查更新的回答我在你建议我不能传递组件时就这么做了。同样的错误。你能看看我在fir里链接的回复吗