Javascript React:在组件的两个层次结构之间传递状态的上下文

Javascript React:在组件的两个层次结构之间传递状态的上下文,javascript,reactjs,state,react-context,Javascript,Reactjs,State,React Context,我正在开发一个网站,我希望能够访问应用程序中任何地方的状态信息。我尝试了几种实现状态的方法,但始终收到以下错误消息: 元素类型无效:需要字符串(对于内置组件)或类/函数(对于复合组件),但得到:未定义。您可能忘记了从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入 检查SOS的渲染方法 这是我的SOS->index.js文件: import React, { useContext } from 'react'; import axios from 'axios'; import CO

我正在开发一个网站,我希望能够访问应用程序中任何地方的状态信息。我尝试了几种实现状态的方法,但始终收到以下错误消息:

元素类型无效:需要字符串(对于内置组件)或类/函数(对于复合组件),但得到:未定义。您可能忘记了从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入

检查SOS的渲染方法

这是我的SOS->index.js文件:

import React, { useContext } from 'react';
import axios from 'axios';
import CONST from '../utils/Constants';
import { Grid, Box, Container } from '@material-ui/core';
import { styled } from '@material-ui/styles';
import { Header } from '../Layout';
import ListItem from './ListItem';
import SOSButton from './SOSButton';
import FormPersonType from './FormPersonType';
import FormEmergencyType from './FormEmergencyType';
import StateContext from '../App';
import Context from '../Context';

export default function SOS() {
  const { componentType, setComponentType } = useContext(Context);
  const timerOn = false;
  //'type_of_person',
  const ambulance = false;
  const fire_service = false;
  const police = false;
  const car_service = false;

  //static contextType = StateContext;
  const showSettings = event => {
    event.preventDefault();
  };

  const handleComponentType = e => {
    console.log(e);
    //this.setState({ componentType: 'type_of_emergency' });
    setComponentType('type_of_emergency');
  };

  const handleEmergencyType = new_emergency_state => {
    console.log(new_emergency_state);
    //   this.setState(new_emergency_state);
  };

  const onSubmit = e => {
    console.log('in OnSubmit');
    axios
      .post(CONST.URL + 'emergency/create', {
        id: 1,
        data: this.state //TODO
      })
      .then(res => {
        console.log(res);
        console.log(res.data);
      })
      .catch(err => {
        console.log(err);
      });
  };

  let component;

  if (componentType == 'type_of_person') {
    component = (
      <FormPersonType handleComponentType={this.handleComponentType} />
    );
  } else if (componentType == 'type_of_emergency') {
    component = (
      <FormEmergencyType
        handleComponentType={this.handleComponentType}
        handleEmergencyType={this.handleEmergencyType}
        emergencyTypes={this.state}
        timerStart={this.timerStart}
        onSubmit={this.onSubmit}
      />
    );
  }
  return (
    <React.Fragment>
      <Header title="Send out SOS" />
      <StateContext.Provider value="type_of_person" />
      <Container component="main" maxWidth="sm">
        {component}
      </Container>
      {/*component = (
        <HorizontalNonLinearStepWithError
          handleComponentType={this.handleComponentType}
        />*/}
    </React.Fragment>
  );
}
import React,{useContext}来自“React”;
从“axios”导入axios;
从“../utils/Constants”导入常量;
从'@material ui/core'导入{Grid,Box,Container};
从'@material ui/styles'导入{styled};
从“../Layout”导入{Header};
从“./ListItem”导入ListItem;
从“/SOSButton”导入SOSButton;
从“/FormPersonType”导入FormPersonType;
从“./FormEmergencyType”导入FormEmergencyType;
从“../App”导入StateContext;
从“../Context”导入上下文;
导出默认函数SOS(){
const{componentType,setComponentType}=useContext(Context);
常数timerOn=false;
//“人的类型”,
常数=假;
const fire_service=错误;
警察=假;
const car_service=false;
//静态上下文类型=StateContext;
const showSettings=事件=>{
event.preventDefault();
};
常量handleComponentType=e=>{
控制台日志(e);
//this.setState({componentType:'type_of_emergency'});
setComponentType(“紧急情况类型”);
};
const HANDLEEMGENCYTYPE=新\紧急\状态=>{
控制台日志(新的紧急状态);
//本.设置状态(新的紧急状态);
};
const onSubmit=e=>{
log('in OnSubmit');
axios
.post(CONST.URL+“紧急情况/创建”{
id:1,
数据:this.state//TODO
})
。然后(res=>{
控制台日志(res);
console.log(res.data);
})
.catch(错误=>{
控制台日志(err);
});
};
let组件;
如果(componentType=='type\U of\U person'){
组件=(
);
}else if(组件类型==“紧急类型”){
组件=(
);
}
返回(
{component}
{/*组件=(
*/}
);
}
我非常感谢你的帮助

上下文文件定义如下,仅供参考:

import React, { useState } from 'react';

export const Context = React.createContext();

const ContextProvider = props => {
  const [componentType, setComponentType] = useState('');
  setComponentType = 'type_of_person';
  //const [storedNumber, setStoredNumber] = useState('');
  //const [functionType, setFunctionType] = useState('');
  return (
    <Context.Provider
      value={{
        componentType,
        setComponentType
      }}
    >
      {props.children}
    </Context.Provider>
  );
};

export default ContextProvider;
import React,{useState}来自“React”;
export const Context=React.createContext();
const ContextProvider=props=>{
常量[componentType,setComponentType]=useState(“”);
setComponentType='type_of_person';
//常量[storedNumber,setStoredNumber]=使用状态(“”);
//const[functionType,setFunctionType]=useState(“”);
返回(
{props.children}
);
};
导出默认上下文提供者;
编辑:我已根据您的建议(上面已更新)更改了代码。但现在我遇到以下错误:
类型错误:无法读取未定义上下文的属性“componentType”

Context
不是从
./Context
文件的默认导出,因此您必须将其作为以下内容导入:

从“../Context”导入{Context};

否则,它将尝试导入您的
Context.Provider
组件

对于文件结构/命名,正确的用法是:

//主应用程序文件(例如)
//将应用程序包装在上下文提供程序中,以便您可以在MyApp中的任何位置访问它
从“../Context”导入ContextProvider
导出默认值()=>{
返回(
)
}
//要在其中使用上下文的文件
从“React”导入React,{useContext}
从“../Context”导入{Context}
导出默认值()=>{
const myCtx=useContext(上下文)
返回(
从上下文中获取了此值-{myCtx.someValue}
)
}

看在上帝的份上……将上下文文件、提供程序和其中的所有内容重命名为更明确的名称。我甚至写这篇文章都感到困惑。

这样做无法更改受影响的
的值。您需要使用第二个位置返回的函数,即
useState
const[impacted,setimpacted]=useState(“”);setimpacted('type_of_person');
如果我取消对呈现函数的注释,这是什么意思?您编写的是一个函数组件,而不是基于类的组件;它没有
render
方法。您需要阅读函数和类组件!另外,
useContext(Context)
将返回一个对象,因此如果
componentType==“type\u of_person”
,则无法执行此操作。您可以使用
const{impact:componentType}=useContext(Context)访问它
@Macabeus谢谢,你能帮我解决你在编辑问题时看到的新错误吗?谢谢!我如何修改除主应用程序文件之外的其他文件中的上下文属性?调用通过上下文传递的setComponentType函数。你的上下文(设置方式)是一个对象。因此,当您调用
const myCtx=useContext(Context)
时,您将可以访问
myCtx.componentType
myCtx.setComponentType()
。如果它现在坏了,那是因为您的上下文文件中有
setComponentType='type\u of_person'
。请删除该文件,并使用
const[componentType,setComponentType]=useState('type\u of_person')设置初始上下文。