【发布时间】:2021-10-07 07:09:51
【问题描述】:
我遇到了一个问题,每次我将道具从一个组件传递到另一个组件时都会收到未定义的错误。我有两个组件,我试图将道具从父组件传递给子组件。我的 App 组件正在执行一个名为 getSession() 的 Redux 操作,以通过 api 调用从我们的主应用程序中获取会话数据,以便在此反应应用程序中使用。我正在使用 componentDidMount 函数来执行此操作。
import './App.css';
import React, {Component} from 'react';
import QuickClassifyHeader from './components/Header';
import StudentCourseTable from './components/StudentCourseTable';
import CourseSearch from './components/CourseSearch';
import CourseApproval from './components/CourseApproval';
import {BrowserRouter,Route, Switch} from "react-router-dom";
import { Layout, Drawer, Button } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import { connect } from 'react-redux';
import { getSession } from './components/redux/actions/sessionActions';
const { Content } = Layout;
class App extends Component{
state = {
visible: false,
}
//initialize props when this component turns on
// constructor(props){
// super(props);
// }
componentDidMount()
{
//call get session action
this.props.getSession();
}
showDrawer = () => {
this.setState({
visible: true,
});
}
onClose = () => {
this.setState({
visible: false,
});
}
render()
{
const sessionCId = this.props.session["contactID"];
console.log("CONTACT ID: " + sessionCId);
return (
<div className="App">
<BrowserRouter basename={'quickclassify/'}>
<Switch>
<Route exact path="/" render={() =>
<Layout hasSider="true" >
<Content>
<Drawer
title="Course Search"
placement="left"
closable={true}
visible={this.state.visible}
onClose={this.onClose}
key="left"
width="40%">
<CourseSearch/>
</Drawer>
<div style={{zIndex: '2', position: 'absolute', top: '10px', left: '10px'}}>
<Button
type="primary"
size="large"
shape="circle"
onClick={this.showDrawer}
icon={<SearchOutlined />}></Button>
</div>
<QuickClassifyHeader contactID={sessionCId}></QuickClassifyHeader>
<StudentCourseTable />
</Content>
</Layout>
}
/>
<Route path="/quickclassify/course-approval" component={CourseApproval} />
</Switch>
</BrowserRouter>
</div>
)
}
}
const mapStateToProps = state => ({
session: state.session.item
});
export default connect(mapStateToProps, { getSession })(App);
获得会话后,我通过“contactID”道具将从该会话状态接收到的联系人 ID 传递给我的标头组件。使用该contactID,我在该组件的useEffect() 中调用另一个名为getCoursework() 的操作来提取特定学生的课程作业。我遇到的问题是,当我将contactID 作为道具传递时,我将contactID 设置为未定义。
import React, { useEffect } from "react";
import { Row, Col, Button, Input, Tag, Spin } from 'antd';
import { BrowserRouter, Link } from "react-router-dom";
import ReusableButton from './common/Button';
import eventBus from '../utils/eventBus';
import {Helmet} from "react-helmet";
import { UserOutlined } from '@ant-design/icons';
import { useSelector } from "react-redux";
import { useDispatch } from "react-redux";
import { getCoursework } from './redux/actions/courseworkAction';
const QuickClassifyHeader = props => {
//redux hooks to grab our coursework state and dispatch
const coursework = useSelector(state => state.coursework.items);
const dispatch = useDispatch();
//contactID prop that was passed in from the App component
const {contactID} = props;
useEffect(() => {
if(contactID != null)
{
//when component mounts on the screen
dispatch(getCoursework(contactID));
}
return() => {
//when the component is unmounting...
console.log("unmounting...")
}
}, []);
let profile = new Object();
profile = coursework['studentProfile'];
console.log(JSON.stringify(profile));
//TODO: Figure out what to do with these constants later
const degree = "";
const program = "";
const dob = "";
const formerName = "";
const name = "";
const concentration = "";
if(profile != null)
{
return (
<div style={{backgroundColor: '#ffffff', borderBottom: 'solid 3px #88288A'}}>
<Helmet>
<title>QuickClassify - Main Screen</title>
<link rel="icon" type="image/png" href="https://www.excelsior.edu/wp-content/uploads/2019/02/cropped-ec-favicon-32x32.png" sizes="32x32"/>
</Helmet>
<Row style={{paddingTop: '10px'}}>
<Col span={2}></Col>
<Col span={10}>
<Input
prefix={<UserOutlined />}
size="middle"
placeholder="Search for a Contact ID..."
// onKeyPress={handleKeyPress}
value={props.contactID}
/>
</Col>
<Col span={12} style={{textAlign: 'right', paddingRight: '10px'}}>
<a style={{ marginRight: '20px'}}>Proofing SR</a>
<img src="https://sistest.int.excelsior.edu/sis/images/folder.gif" style={{ marginRight: '20px', marginBottom: '5px', height: '24px'}} />
<img src="https://sistest.int.excelsior.edu/sis/images/map2.gif" style={{height: '24px'}} />
</Col>
</Row>
<Row style={{padding: '10px 10px'}}>
<Col span={2} style={{textAlign: 'left'}}></Col>
<Col span={12} style={{textAlign: 'left'}}>
<Tag color="#88288A" style={{marginRight: '10px'}}><b>Name</b> {profile.firstName}</Tag>
<Tag color="#88288A" style={{marginRight: '10px'}}><b>Degree</b> {profile.svcProgramCode}</Tag>
<Tag color="#88288A" style={{marginRight: '10px'}}><b>Concentration</b> {profile.concentrationCode}</Tag>
<Tag color="#88288A" style={{marginRight: '10px'}}><b>Program</b> {profile.svcProgramCode}</Tag>
<Tag color="#88288A" style={{marginRight: '10px'}}><b>DOB</b> {profile.dob}</Tag>
<Tag color="#88288A" style={{marginRight: '10px'}}><b>Former Names</b> {profile.formerNames}</Tag>
</Col>
<Col span={10} style={{textAlign: 'right'}}>
<Button
style={{marginRight: '10px'}}
type="primary"
// onClick={handleSaveButtonClicked}
>
Save Changes
</Button>
<BrowserRouter>
<Link
to="/course-approval"
target="_blank"
>
<ReusableButton
colSize={3}
btnName="Course Approval"
/>
</Link>
</BrowserRouter>
</Col>
</Row>
<Spin
size="large"
//TODO: Set up loading for this component later.
spinning={false}
delay={500}
style={{ position: 'absolute',
top: '200px',
left: '49%',
backgroundColor: '#ffffff',
border: 'solid 3px #88288A',
padding: '50px 50px',
zIndex: '1001'
}} />
</div>
);
}
return (
<div style={{backgroundColor: '#ffffff', borderBottom: 'solid 3px #88288A'}}>
<Helmet>
<title>QuickClassify - Main Screen</title>
<link rel="icon" type="image/png" href="https://www.excelsior.edu/wp-content/uploads/2019/02/cropped-ec-favicon-32x32.png" sizes="32x32"/>
</Helmet>
<Row style={{paddingTop: '10px'}}>
<Col span={2}></Col>
<Col span={10}>
<Input
prefix={<UserOutlined />}
size="middle"
placeholder="Search for a Contact ID..."
// onKeyPress={handleKeyPress}
value={props.contactID}
/>
</Col>
<Col span={12} style={{textAlign: 'right', paddingRight: '10px'}}>
<a style={{ marginRight: '20px'}}>Proofing SR</a>
<img src="https://sistest.int.excelsior.edu/sis/images/folder.gif" style={{ marginRight: '20px', marginBottom: '5px', height: '24px'}} />
<img src="https://sistest.int.excelsior.edu/sis/images/map2.gif" style={{height: '24px'}} />
</Col>
</Row>
<Row style={{padding: '10px 10px'}}>
<Col span={2} style={{textAlign: 'left'}}></Col>
<Col span={12} style={{textAlign: 'left'}}>
<Tag color="#88288A" style={{marginRight: '10px'}}><b>Name</b></Tag>
<Tag color="#88288A" style={{marginRight: '10px'}}><b>Degree</b></Tag>
<Tag color="#88288A" style={{marginRight: '10px'}}><b>Concentration</b></Tag>
<Tag color="#88288A" style={{marginRight: '10px'}}><b>Program</b></Tag>
<Tag color="#88288A" style={{marginRight: '10px'}}><b>DOB</b></Tag>
<Tag color="#88288A" style={{marginRight: '10px'}}><b>Former Names</b></Tag>
</Col>
<Col span={10} style={{textAlign: 'right'}}>
<Button
style={{marginRight: '10px'}}
type="primary"
// onClick={handleSaveButtonClicked}
>
Save Changes
</Button>
<BrowserRouter>
<Link
to="/course-approval"
target="_blank"
>
<ReusableButton
colSize={3}
btnName="Course Approval"
/>
</Link>
</BrowserRouter>
</Col>
</Row>
<Spin
size="large"
//TODO: Set up loading for this component later.
spinning={false}
delay={500}
style={{ position: 'absolute',
top: '200px',
left: '49%',
backgroundColor: '#ffffff',
border: 'solid 3px #88288A',
padding: '50px 50px',
zIndex: '1001'
}} />
</div>
);
}
export default QuickClassifyHeader;
【问题讨论】:
-
您可以尝试在您的 useEffect 中的
if(contactID != null)块内记录contactID 吗?它的价值是否与您期望的价值相匹配?另外,请确认App.js中的console.log("CONTACT ID: " + sessionCId);没有为sessionCId显示未定义。 -
我已经检查了 cessionCId 并且该变量在我相信的第二次渲染中显示了联系人 ID 值。我现在将检查条件。
-
是的@KevinHaxhi。我相信 useEffect 忽略了条件。如果 contactID 不为 null 并且 chrome 中的日志上没有显示任何内容,我会从它中取出调度以测试日志记录。
标签: reactjs redux react-redux