如何在 React 中切换组件?
how to switch component in React?
我想让用户在创建内容后移动主要组件,但我不知道我需要使用什么方法。我想使用 history 之类的东西,但没有用。我正在使用
- "反应": "^17.0.2",
- "react-dom": "^17.0.2",
- "react-router-dom": "^6.2.1",
import React, { Component } from 'react';
class CreateContent extends Component {
constructor(props) {
super(props);
this.state = {
content: {
title: ''
}
}
}
handleInput = (e) => {
this.setState({
content : {
...this.state.content,
[e.target.name]: e.target.value
}
})
}
addContent = async (e) => {
e.preventDefault();
console.log(JSON.stringify(this.state.title))
try {
const response = await fetch('http://localhost:9000/api/v1/content', {
method: 'POST',
body: JSON.stringify(this.state.content),
mode:'cors',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json'
}
});
if(!response.ok) {
throw Error(response.statusText)
}
// ******* HERE I wanted to add something like *******
history.push('/main')
} catch (err) {
console.log('addContent failed -', err)
}
}
render() {
return (
<div>
<form onSubmit={this.addContent}>
<input
type="text"
name="title"
onChange={this.handleInput}
value={this.state.content.title}
/>
<input type="submit" value="submit" />
</form>
</div>
)
}
}
export default CreateContent
在react中可以通过多种方式实现重定向
1- 只需使用 react-router-dom
中的 Link
<Link to={"/my-route"} />
2- 您可以使用来自 react-router-dom
的 useNavigate
const navigate = useNavigate()
navigate("/my-route")
3- 如果
,您可以简单地将状态用于 show/hide 组件
const [visibleComponent, setVisibleComponent] = useState('component1')
<Component1 isVisible={visibleComponent === 'component1'} />
<Component2 isVisible={visibleComponent === 'component2'} />
<Component3 isVisible={visibleComponent === 'component3'} />
然后您可以根据您的逻辑更改组件 (setVisibleComponent('component2') 以显示第二个组件,依此类推...
在React Router v6
中,你需要使用useNavigate而不是history.push().
但是,由于您正在使用 class 组件 React Router v6
it doesn't support these hooks out of the box for the class components。这就是您收到错误的原因:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
但这并不意味着你不能使用它。您可以使用 HOC 重新创建它:
import {
useLocation,
useNavigate,
useParams
} from "react-router-dom";
function withRouter(Component) {
function ComponentWithRouterProp(props) {
let location = useLocation();
let navigate = useNavigate();
let params = useParams();
return (
<Component
{...props}
router={{ location, navigate, params }}
/>
);
}
return ComponentWithRouterProp;
}
您现在可以将 class-based 组件以非常熟悉的方式包装并导出到 withRouter
HOC,它们来自 v4/v5。
之后您可以使用 react-router-dom v6
中的 useNavigate
。
const navigate = useNavigate()
navigate("/main")
关于您在评论中提到的问题:
So should I create a separate component to add the above code or I should add the above code for each component that I want to use history? or should I add it into App.js?
要首先解决此问题,请创建一个新组件 withRouter
,如上所示,然后在导出时将 CreateContent
组件包装在 withRouter
函数中:
export default withRouter(CreateContent)
withRouter
将在渲染时将更新的匹配、位置和历史属性传递给包装的组件。
withRouter
v5 中的引用:https://v5.reactrouter.com/web/api/withRouter
我想让用户在创建内容后移动主要组件,但我不知道我需要使用什么方法。我想使用 history 之类的东西,但没有用。我正在使用
- "反应": "^17.0.2",
- "react-dom": "^17.0.2",
- "react-router-dom": "^6.2.1",
import React, { Component } from 'react';
class CreateContent extends Component {
constructor(props) {
super(props);
this.state = {
content: {
title: ''
}
}
}
handleInput = (e) => {
this.setState({
content : {
...this.state.content,
[e.target.name]: e.target.value
}
})
}
addContent = async (e) => {
e.preventDefault();
console.log(JSON.stringify(this.state.title))
try {
const response = await fetch('http://localhost:9000/api/v1/content', {
method: 'POST',
body: JSON.stringify(this.state.content),
mode:'cors',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json'
}
});
if(!response.ok) {
throw Error(response.statusText)
}
// ******* HERE I wanted to add something like *******
history.push('/main')
} catch (err) {
console.log('addContent failed -', err)
}
}
render() {
return (
<div>
<form onSubmit={this.addContent}>
<input
type="text"
name="title"
onChange={this.handleInput}
value={this.state.content.title}
/>
<input type="submit" value="submit" />
</form>
</div>
)
}
}
export default CreateContent
在react中可以通过多种方式实现重定向
1- 只需使用 react-router-dom
中的 Link<Link to={"/my-route"} />
2- 您可以使用来自 react-router-dom
的 useNavigateconst navigate = useNavigate()
navigate("/my-route")
3- 如果
,您可以简单地将状态用于 show/hide 组件const [visibleComponent, setVisibleComponent] = useState('component1')
<Component1 isVisible={visibleComponent === 'component1'} />
<Component2 isVisible={visibleComponent === 'component2'} />
<Component3 isVisible={visibleComponent === 'component3'} />
然后您可以根据您的逻辑更改组件 (setVisibleComponent('component2') 以显示第二个组件,依此类推...
在React Router v6
中,你需要使用useNavigate而不是history.push().
但是,由于您正在使用 class 组件 React Router v6
it doesn't support these hooks out of the box for the class components。这就是您收到错误的原因:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
但这并不意味着你不能使用它。您可以使用 HOC 重新创建它:
import {
useLocation,
useNavigate,
useParams
} from "react-router-dom";
function withRouter(Component) {
function ComponentWithRouterProp(props) {
let location = useLocation();
let navigate = useNavigate();
let params = useParams();
return (
<Component
{...props}
router={{ location, navigate, params }}
/>
);
}
return ComponentWithRouterProp;
}
您现在可以将 class-based 组件以非常熟悉的方式包装并导出到 withRouter
HOC,它们来自 v4/v5。
之后您可以使用 react-router-dom v6
中的 useNavigate
。
const navigate = useNavigate()
navigate("/main")
关于您在评论中提到的问题:
So should I create a separate component to add the above code or I should add the above code for each component that I want to use history? or should I add it into App.js?
要首先解决此问题,请创建一个新组件 withRouter
,如上所示,然后在导出时将 CreateContent
组件包装在 withRouter
函数中:
export default withRouter(CreateContent)
withRouter
将在渲染时将更新的匹配、位置和历史属性传递给包装的组件。
withRouter
v5 中的引用:https://v5.reactrouter.com/web/api/withRouter