리액션 라우터 포함 스토리북 - 외부 사용 금지
문제의 해결책을 게시하는 것은 선생님 구글링 기술이지만 찾기가 어려웠습니다.
리액트 라우터를 탑재한 앱은 문제없이 작동했지만 Storybook은 "Invariant failed:<Router> 외부에서 <Link>를 사용하지 마십시오.
Error: Invariant failed: You should not use <Link> outside a <Router>
at invariant (tiny-invariant.esm.js:11)
at react-router-dom.js:181
at updateContextConsumer (react-dom.development.js:19747)
at beginWork$1 (react-dom.development.js:20079)
at HTMLUnknownElement.callCallback (react-dom.development.js:358)
at Object.invokeGuardedCallbackDev (react-dom.development.js:410)
at invokeGuardedCallback (react-dom.development.js:463)
at beginWork$$1 (react-dom.development.js:25730)
at performUnitOfWork (react-dom.development.js:24631)
at workLoopSync (react-dom.development.js:24613)
이상하게도 앱이 작동하기 때문에 <Router> 이외에서는 <Link>가 사용되지 않았습니다.
다음과 같은 이점이 있습니다.
- 작성하다
preview.js파일을 제출하다.storybook폴더입니다. - 다음 글로벌 데코레이터 추가
preview.js파일.
import React from "react";
import { addDecorator } from "@storybook/react";
import { MemoryRouter } from "react-router";
addDecorator(story => <MemoryRouter initialEntries={['/']}>{story()}</MemoryRouter>);
메모들
편집 : 스토리북 V7 업데이트(2022년 12월)
이름 바꾸기
preview.js로.preview.tsx(jsx에서도 동일하게 동작한다고 생각합니다만, 제 프로젝트는 TypeScript로 되어 있습니다.)addDecoratorv7에서는 기능을 사용할 수 없기 때문에 이렇게 추가해야 합니다.
import React from "react";
import { MemoryRouter } from "react-router";
export const decorators = [
(Story) => (
<MemoryRouter initialEntries={['/']}>
<Story />
</MemoryRouter>
),
];
이게 나한테 효과가 있었어.데코레이터 속성 내에 메모리 라우터를 추가합니다.
import React from 'react';
import {MemoryRouter} from 'react-router-dom';
import //your component// from //component location//
export default {
title : //How you want your component to show in storybook eg: 'Components/Button'
component : //Specify the name of component that you imported eg: 'Button'
decorators : [(Story) => (<MemoryRouter><Story/></MemoryRouter>)] //Wrapping the story inside the router
};
Storybook 버전 6.1에서는 새로운 코드 표기법으로 스토리북 라우터가 동작합니다.단일 컴포넌트의 예를 다음에 나타냅니다.
import React from 'react';
import StoryRouter from 'storybook-react-router';
import //your component// from //component location//
export default {
title: '//your component//',
component: //your component//,
decorators: [StoryRouter()],
};
export const Name = () => <//your component// />;
Web-ski의 답변에 대해 더 말해 주세요.StoryRouter 추가.storybook/preview.js
import StoryRouter from 'storybook-react-router';
addDecorator(StoryRouter());
현재는 전 세계에서 모든 스토리에서 이용할 수 있습니다.
글로벌이 아닌 개별 컴포넌트에 대해 이 작업을 수행하려면 스토리 파일에서 컴포넌트를 메모리라우터로 랩합니다.
예를 들어 헤더 컴포넌트에 Link 요소가 포함되어 있기 때문에 header.stories.tsx 파일에서 다음을 변경합니다.
const Template: ComponentStory<typeof Header> = (args) => (
<Header {...args} />
);
로.
const Template: ComponentStory<typeof Header> = (args) => (
<MemoryRouter>
<Header {...args} />
</MemoryRouter>
);
현재 가장 많은 표를 얻고 있는 Fabian의 답변은 React Router의 데이터 API를 사용하고 싶지 않은 경우에만 문제를 해결합니다.
다음은 리액트 라우터의 데이터 API를 사용할 수 있는 기능을 추가한 Fabian의 수정판 회피책입니다.이를 통해 확장 컴포넌트와 같은 데이터 라우터 고유의 기능을 사용할 수 있습니다.
import { createMemoryRouter, RouterProvider } from "react-router-dom";
import { addDecorator } from "@storybook/react";
addDecorator((story) => {
const router = createMemoryRouter([{ path: "/", element: story() }], {
initialEntries: ["/"],
});
return <RouterProvider router={router} />;
});
문제는 Storybook이 개별 스토리를 만드는 것이었습니다.이 경우 구성 요소는 다음을 사용합니다.<Link>실제로 외부로 전달되었다<Router>.
해결책은 개별 스토리를 정리하는 것이었습니다.<Router>addDecorator 사용;
//config.js
//...
addDecorator(story => <Router>{story()}</Router>);
루트 패스 파라미터도 사용하려면 스토리북 데코레이터를 사용해야 합니다.사용자 Web-ski와 sidonaldson은 이미 스토리북에 라우터 모크를 추가하는 방법을 보여 주었다.
리액트 v18에서의 스토리북 라우터 모의 구현입니다.
preview.preview 파일
import { withRouter } from "storybook-addon-react-router-v6";
export const decorators = [withRouter];
component.story.component 파일
import Component from "./component";
export default {
component: Component,
title: "component with rout path and parameters",
parameters: {
reactRouter: {
routePath: "/root/:primary/:secondary",
routeParams: { primary: "firstparam", secondary: "secondparam" },
},
},
};
const Template = (args) => <Component {...args} />;
export const Default = Template.bind({});
Default.args = {
// ommited
};
그러면 useParams와 같은 함수에 다음과 같은 결과가 나타납니다.
const {primary, secondary} = useParams();
console.log('primary value: ' + primary)
console.log('secondary value: ' + secondary)
// outputs: primary value: firstparam
// outputs: secondary value: secondparam
언급URL : https://stackoverflow.com/questions/58909666/storybook-w-react-router-you-should-not-use-link-outside-router
'source' 카테고리의 다른 글
| jQuery ready 기능이 WordPress에서 작동하지 않습니다. (0) | 2023.03.06 |
|---|---|
| 반응 원어민에서 터치 가능 영역 제어 (0) | 2023.03.06 |
| Tymeleaf: 변수가 정의되어 있는지 확인합니다. (0) | 2023.03.06 |
| Word press admin-ajax에서 오류 302 리다이렉트 발생 (0) | 2023.03.06 |
| Nodejs/Express용 Mongodb 드라이버와 함께 Mongodb를 직접 사용하는 대신 Mongoose ODM을 사용해야 하는 이유는 무엇입니까? (0) | 2023.03.06 |