reactjs - Storybook 不呈现故事,错误:“useContext(...) 未定义”
问题描述
如果我为以下组件创建故事,我只会在红框中收到几条消息,其中不包含任何我可以从中获得任何见解的信息:
import React, { useState, useContext } from "react";
import { FormGroup, FormControl, Col } from "react-bootstrap";
import Button from "../button/Button";
import AuthContext from "../../AuthContext";
import { useHistory } from "react-router-dom";
import LoginWarning from "./LoginWarning";
export function Login(props) {
const [email, setEmail2] = useState("");
const [password, setPassword] = useState("");
const [showAlert, setShowAlert] = useState(false);
const {
setRole,
setName,
setEmail,
setSessionId,
setLocalStorage
} = useContext(AuthContext);
let history = useHistory();
function validateForm() {
return email.length > 0 && password.length > 0;
}
const loginPost = {
email: email,
password: password
};
function handleSubmit(event) {
event.preventDefault();
const fetchUserInfo = async () => {
const result = await fetch(`/account`, {
method: "GET"
});
const body = await result.json();
console.log(body);
setRole(body.role);
setName(body.name);
setEmail(body.email);
history.push("/home");
};
const fetchAuth = async () => {
const result = await fetch(`/login`, {
method: "POST",
body: JSON.stringify(loginPost),
headers: {
"Content-Type": "application/json"
}
});
const body = await result.json();
console.log(body);
if (body.isUser === true) {
setSessionId(body.sessionId);
setLocalStorage(body.sessionId);
fetchUserInfo();
} else {
setShowAlert(true);
}
};
fetchAuth();
}
return (
<div>
{showAlert ? <LoginWarning /> : null}
<form onSubmit={handleSubmit}>
<Col lg={6}>
<FormGroup controlId="email" bsSize="large">
<label>Email</label>
<FormControl
autoFocus
type="email"
value={email}
onChange={e => setEmail2(e.target.value)}
/>
</FormGroup>
</Col>
<Col lg={6}>
<FormGroup controlId="password" bsSize="large">
<label>Passwort</label>
<FormControl
value={password}
onChange={e => setPassword(e.target.value)}
type="password"
/>
</FormGroup>
<Button disabled={!validateForm()} type="submit" text="Login" />
</Col>
</form>
</div>
);
}
export default Login;
故事是这样的:
import React from "react";
import { Login } from "./Login";
import { storiesOf } from "@storybook/react";
export default {
title: "Login Form"
};
storiesOf("Login Form", module).add("default", () => <Login />);
这就是 Storybook 所展示的。由于我的组件在应用程序中显示没有任何问题,我无法弄清楚是什么导致 Storybook 出现问题:
useHistory@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:100829:10
Login@http://localhost:6006/main.e31f087434cfd38286ae.bundle.js:763:84
renderWithHooks@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:84742:27
mountIndeterminateComponent@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:87276:13
beginWork$1@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:88638:16
callCallback@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:68837:14
invokeGuardedCallbackDev@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:68886:16
invokeGuardedCallback@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:68941:31
beginWork$$1@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:94239:28
performUnitOfWork@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:93166:12
workLoopSync@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:93139:22
performSyncWorkOnRoot@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:92738:11
scheduleUpdateOnFiber@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:92166:28
updateContainer@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:95562:15
legacyRenderSubtreeIntoContainer/<@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:95986:22
unbatchedUpdates@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:92901:12
legacyRenderSubtreeIntoContainer@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:95985:21
render@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:96073:12
render/<@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:20472:26
render@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:20471:10
_callee$@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:20563:20
tryCatch@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:19561:40
invoke@http://localhost:6006/vendors~main.e31f087434cfd38286ae.bundle.js:19787:30
defineIteratorMethods/
浏览器控制台显示以下内容:
The above error occurred in the <Login> component:
in Login (at Login.stories.js:10)
in AuthProvider (at Login.stories.js:10)
in storyFn
in ErrorBoundary
React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary. react-dom.development.js:21810
React 18
render render.js:70
render render.js:69
_callee$ render.js:161
Babel 8
_callee$ start.js:408
Babel 8
renderUI start.js:453
emit index.js:180
setSelection story_store.js:325
TypeError: "useContext(...) is undefined"
useHistory react-router.js:706
Login Login.js:19
React 16
render render.js:70
render render.js:69
_callee$ render.js:161
Babel 8
_callee$ start.js:408
Babel 8
renderUI start.js:453
emit index.js:180
setSelection story_store.js:325
解决方案
如果您的组件使用useContext()
,您实际上必须初始化上下文。Storybook 与您的应用程序具有不同的入口点,因此除非您自己进行,否则所有正常的应用程序初始化都不会发生。
最简单的方法是使用装饰器(请参阅https://storybook.js.org/docs/addons/introduction/)。
要在全局范围内执行此操作,请在您的.storybook/config.js
:
const StorybookWrapper = (storyFn) => (
<YourContextProvider>
{storyFn()}
</YourContextProvider>
);
addDecorator(StorybookWrapper);
推荐阅读
- nativescript - 创建新的共享 NativeScript 项目不起作用
- c# - 如何使用 azure hub 向某些用户发送批量推送通知
- powershell - 文本文件中的Powershell ForEach-Object行拆分比较和删除
- android - Android Studio 中的文件与文件资源管理器中的文件不匹配
- rabbitmq - 我应该创建一些交易所 Rabbit MQ 吗?
- elasticsearch - 将 Elasticsearch 数据保留限制在磁盘空间以下
- javascript - Gmail api - 浏览器快速入门错误:错误请求
- laravel - Laravel Passport 未使用 JWT cookie 进行身份验证(自用 API)
- javascript - aws s3 sdk 是否具有与 aws s3 cp 相同或等效的命令?
- laravel - Laravel 主键不允许为空