我正在运行一个React应用程序。
当我通过路线进入页面时(单击按钮或链接),页面工作正常,但是当我重新加载页面时,页面崩溃。我看不到错误在哪里,控制台和源显示为空白,这是服务器消息控制台消息。
server: Entrypoint index [big] = index.js index.1af9d975ff74be4d27d9.hot-update.js index.c93bf08301ec20c0dc85.js.map index.c93bf08301ec20c0dc85.js.map
server: 533 modules
server: backend debug read session { csrfToken: '0ae87c36d850008df20b58941bf89072', id: 2 }
server: backend debug {"data":{"currentUser":null}} <= undefined
server: backend debug {"data":{"currentUser":null}} <= undefined
server: backend debug read session {}
server: backend error TypeError: Cannot convert undefined or null to object
server: at getPrototypeOf (<anonymous>)
server: at hoistNonReactStatics (/Users/apple/Desktop/dev/bethabit/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js:71:38)
server: at resolveComponent (/Users/apple/Desktop/dev/bethabit/node_modules/@loadable/component/dist/loadable.cjs.js:332:3)
server: at InnerLoadable.loadSync (/Users/apple/Desktop/dev/bethabit/node_modules/@loadable/component/dist/loadable.cjs.js:189:24)
server: at new InnerLoadable (/Users/apple/Desktop/dev/bethabit/node_modules/@loadable/component/dist/loadable.cjs.js:138:17)
server: at processChild (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3048:14)
server: at resolve (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3013:5)
server: at ReactDOMServerRenderer.render (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3436:22)
server: at ReactDOMServerRenderer.read (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3395:29)
server: at renderToStaticMarkup (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3969:27)
server: at process (/Users/apple/Desktop/dev/bethabit/node_modules/@apollo/react-ssr/lib/react-ssr.cjs.js:38:16)
server: at process._tickCallback (internal/process/next_tick.js:68:7)
server: backend debug read session { id: 3 }
server: backend debug loading <= currentUser
server: backend debug loading <= currentUser
server: backend debug loading <= currentUser
server: backend debug {"data":{"currentUser":{"id":3,"username":"canercak@gmail.com","role":"user","isActive":true,"email":"canercak@gmail.com","__typename":"User"}}} <= currentUser
server: backend debug {"data":{"currentUser":{"id":3,"username":"canercak@gmail.com","role":"user","isActive":true,"email":"canercak@gmail.com","__typename":"User"}}} <= currentUser
server: backend debug {"data":{"currentUser":{"id":3,"username":"canercak@gmail.com","role":"user","isActive":true,"email":"canercak@gmail.com","profile":{"firstName":"Caner","lastName":"Çakmak","fullName":"Caner Çakmak","__typename":"UserProfile"},"auth":{"certificate":null,"facebook":{"fbId":null,"displayName":null,"__typename":"FacebookAuth"},"google":{"googleId":"104801577244556473676","displayName":"Caner Çakmak","__typename":"GoogleAuth"},"github":null,"linkedin":null,"__typename":"UserAuth"},"__typename":"User"}}} <= currentUser
server: backend debug read session {}
server: backend error TypeError: Cannot convert undefined or null to object
server: at getPrototypeOf (<anonymous>)
server: at hoistNonReactStatics (/Users/apple/Desktop/dev/bethabit/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js:71:38)
server: at resolveComponent (/Users/apple/Desktop/dev/bethabit/node_modules/@loadable/component/dist/loadable.cjs.js:332:3)
server: at InnerLoadable.loadSync (/Users/apple/Desktop/dev/bethabit/node_modules/@loadable/component/dist/loadable.cjs.js:189:24)
server: at new InnerLoadable (/Users/apple/Desktop/dev/bethabit/node_modules/@loadable/component/dist/loadable.cjs.js:138:17)
server: at processChild (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3048:14)
server: at resolve (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3013:5)
server: at ReactDOMServerRenderer.render (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3436:22)
server: at ReactDOMServerRenderer.read (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3395:29)
server: at renderToStaticMarkup (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3969:27)
server: at process (/Users/apple/Desktop/dev/bethabit/node_modules/@apollo/react-ssr/lib/react-ssr.cjs.js:38:16)
server: at process._tickCallback (internal/process/next_tick.js:68:7)
这是运行的代码。我尝试删除currentuser,addhabit和许多其他内容,只是为了了解错误的出处。没有结果。如果我通过链接进入页面,一切正常。
HabitaddView.web.jsx
const HabitAddView = ({ addHabit, t, currentUser }) => {
const renderMetaData = () => (
<Helmet
title={`${settings.app.name} - ${t('habit.title')}`}
meta={[
{
name: 'description',
content: t('habit.meta')
}
]}
/>
);
return (
<PageLayout>
{renderMetaData()}
<div className="row">
<div className="col-sm-12 padTop10">
<h2>{t(`habit.label.create_new`)}</h2>
</div>
</div>
<HabitForm onSubmit={onSubmit(addHabit)} currentUser={currentUser} />
</PageLayout>
);
};
HabitForm.web.jsx
const HabitForm = ({ values, handleSubmit, setFieldValue, submitting, t }) => {
const [habitType, sethabitType] = useState('Fitness Habits');
const [intervalText, setIntervalText] = useState(t('habit.field.interval'));
const [habitActions, sethabitActions] = useState([]);
const [habitFreqs, sethabitFreqs] = useState([]);
const [habitDurations, sethabitDurations] = useState([]);
const [habitIntervals, sethabitIntervals] = useState([]);
const [showInterval, setshowInterval] = useState(true);
const [showHabitDiv, setshowHabitDiv] = useState(false);
const [habitActionDisabled, sethabitActionDisabled] = useState(true);
let calendarComponentRef = React.createRef();
let calendarWeekends = true;
let [calendarEvents, setCalendarEvents] = useState([]);
var timeZones = moment.tz.names();
const handleHabitTypeChange = (type, value, setFieldValue) => {
setFieldValue(type, value);
resetValues();
Object.values(settings.habits.list).map(object => {
if (object.habit_type == value) {
const _habitActions = [];
Object.values(object.habit_actions).map(object2 => {
_habitActions.push(object2.title);
});
sethabitType(value);
sethabitActions(_habitActions);
setshowHabitDiv(false);
sethabitActionDisabled(false);
}
});
};
const updateIntervalText = worktype => {
if (worktype === 5) {
setIntervalText(t('habit.field.number'));
} else if (worktype === 6 || worktype === 7) {
setIntervalText(t('habit.field.proof'));
} else {
setIntervalText(t('habit.field.interval'));
}
};
const handleHabitActionChange = (type, value, setFieldValue) => {
const preparedValue = Array.isArray(value) ? value[0] : value;
setFieldValue(type, preparedValue);
const _habitFreqs = [];
const _habitDurations = [];
const _habitIntervals = [];
resetValues();
Object.values(settings.habits.list).map(object => {
if (object.habit_type == habitType) {
Object.values(object.habit_actions).map(object2 => {
if (object2.title == preparedValue) {
Object.values(object2.duration).map(object4 => {
_habitDurations.push(object4);
});
Object.values(object2.interval).map(object5 => {
_habitIntervals.push(object5);
});
sethabitFreqs(_habitFreqs);
sethabitIntervals(_habitIntervals);
sethabitDurations(_habitDurations);
setshowHabitDiv(true);
setFieldValue('timezone', moment.tz.guess());
setFieldValue('worktype', object2.worktype);
setFieldValue('description', object2.description);
setFieldValue('misc', JSON.stringify(object2.misc));
updateIntervalText(object2.worktype);
}
});
}
});
};
const handleValueChange = (type, value, setFieldValue) => {
const preparedValue = value;
setFieldValue(type, preparedValue);
let timezone = values.timezone;
let interval = values.interval;
let duration = values.duration;
if (type === 'timezone') {
timezone = value;
} else if (type === 'interval') {
interval = value;
} else if (type === 'duration') {
duration = value;
}
updateCalendarEvents(values.habit_action, timezone, interval, duration);
};
const empty = e => {
switch (e) {
case '':
case 0:
case '0':
case null:
case false:
case typeof this == 'undefined':
return true;
default:
return false;
}
};
const resetValues = () => {
values.duration = '';
values.interval = '';
values.timezone = '';
updateCalendarEvents(values.habit_action, values.timezone, values.interval, values.duration);
};
const updateCalendarEvents = (habit_action, timezone, interval, duration) => {
setCalendarEvents([]);
let events = [];
if (!empty(timezone) && !empty(interval) && !empty(duration)) {
var dur = JSON.parse(duration);
var int = JSON.parse(interval);
var times = dur.count;
var counter = 0;
for (var i = 0; i < times; i++) {
if (i % int.step === 0) {
counter += 1;
var obj = {
title: values.habit_action + ' ' + int.title,
start: moment
.tz(values.timezone)
.add(i + 1, 'days')
.format(),
allDay: true
};
let addObj = true;
if (values.worktype === 7 && i === 0) {
addObj = false;
}
if (dur.weekdays === true && (moment(obj.start).isoWeekday() === 6 || moment(obj.start).isoWeekday() === 7)) {
addObj = false;
}
if (
values.worktype === 7 &&
counter > 2 &&
counter < 10 &&
(habit_action === 'Stay Alcohol Free' || (habit_action === 'Stay Nicotine Free' && dur.count === 28))
) {
obj.start = moment
.tz(values.timezone)
.add(i + (counter - 1), 'days')
.format();
true;
}
if (addObj) {
events.push(obj);
}
}
}
if (habit_action === 'Stay Alcohol Free' && dur.count === 28) {
events.sort(function(a, b) {
return moment(b.start) - moment(a.start);
});
events.shift();
events.shift();
}
setCalendarEvents(events);
}
};
if (settings.habits.list) {
return (
<div className="row">
<div className="col-sm-5">
<div className="card">
<div className="card-body">
<Form name="habit" onSubmit={handleSubmit}>
<Field
name="habit_type"
component={RenderSelect}
type="select"
label={t('habit.field.habit_type')}
value={values.habit_type}
onChange={value => handleHabitTypeChange('habit_type', value, setFieldValue)}
cols={1}
>
<Option value={0}>--Please Select--</Option>
{Object.values(settings.habits.list).map((object, i) => {
return (
<Option key={i} value={object.habit_type}>
{object.habit_type}
</Option>
);
})}
</Field>
habitadd.jsx
class HabitAdd extends React.Component {
static propTypes = {
currentUser: PropTypes.object
};
constructor(props) {
super(props);
this.subscription = null;
this.state = { options: [] };
}
render() {
if ( this.props.currentUser) {
return <HabitAddView {...this.props} />;
} else {
return <div></div>;
}
}
}
export default compose(
graphql(ADD_HABIT, {
props: ({ ownProps: { history, navigation }, mutate }) => ({
addHabit: async (
habit_type,
habit_action,
duration,
interval,
timezone,
description,
worktype,
misc,
user_id
) => {
let habitData = await mutate({
variables: {
input: {
habit_type: habit_type,
habit_action: habit_action,
duration: duration,
interval: interval,
timezone: timezone,
description: description,
worktype: worktype,
misc: misc,
user_id: user_id
}
},
optimisticResponse: {
__typename: 'Mutation',
addHabit: {
__typename: 'Habit',
id: null,
habit_type: habit_type,
habit_action: habit_action,
duration: duration,
interval: interval,
timezone: timezone,
description: description,
worktype: worktype,
misc: misc,
user_id: user_id,
days: [],
bets: []
}
}
});
if (history) {
window.location.href = window.location.origin + '/habit/' + habitData.data.addHabit.id;
} else if (navigation) {
return navigation.push('HabitEdit', { id: habitData.data.addHabit.id });
}
}
})
}),
graphql(CURRENT_USER_QUERY, {
props({ data: { error, currentUser } }) {
if (error) throw new Error(error);
return { currentUser };
}
})
)(HabitAdd);
感谢Ace,我意识到了自己的错误。 在habitAdd render方法上添加了此代码行
render() {
if ( this.props.currentUser) {
return <HabitAddView {...this.props} />;
} else {
return <div></div>;
}
}
答案 0 :(得分:3)
问题出在currentUser
上。考虑初始化它。在路由之前,我假设您正在设置currentUser
的值或currentUser
设置为一个值,但是在刷新时,虽然组件将加载,但重置了该值,{ {1}}不可用,因此错误。
答案 1 :(得分:0)
VSCode在这里很有帮助。尝试在调试模式下使用-inspect 选项运行节点应用,并选中在异常上暂停选项。
或者,您可以考虑将应用程序配置为具有更长的堆栈跟踪,或者使用类似longjohn [https://www.npmjs.com/package/longjohn]的东西来帮助实现这一目标。