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