【问题标题】:how to switch component in React? [duplicate]如何在 React 中切换组件? [复制]
【发布时间】:2022-03-04 08:55:03
【问题描述】:

我想让用户在创建内容后移动主要组件,我不知道我需要使用什么方法。我想使用类似历史的东西,但它没有用。我正在使用

  • “反应”:“^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 Router。如果我理解正确,您希望用户导航到某个自定义链接,如果是这样,请使用 &lt;Link to="/detail"&gt;Go To Details&lt;/Link&gt; 同样,您将有一些来自详细信息页面的链接返回到 main 页面。
  • @ParagDiwan 我想在函数内部使用它,这样我就可以让用户在他们成功 POST 请求后移动主页。我曾经使用 history.push 但我想它不再工作了..

标签: reactjs react-router react-router-dom


【解决方案1】:

React Router v6 中,您需要使用 useNavigate 而不是 history.push()

但是,由于您使用的是 类组件 React Router v6 it doesn't support these hooks out of the box for the class components。这就是您收到错误的原因:

错误:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用。

但这并不意味着你不能使用它。您可以使用 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;
}

您现在可以以非常熟悉的方式将基于类的组件包装并导出到 withRouter HOC。

之后,您可以使用useNavigate 中的react-router-dom v6

const navigate = useNavigate()
navigate("/main")

关于您在评论中提到的查询:

那么我应该创建一个单独的组件来添加上面的代码,还是应该为我想要使用历史记录的每个组件添加上面的代码?还是应该将其添加到 App.js 中?

要首先解决此问题,请按照上述说明创建一个新组件withRouter,然后在导出时将CreateContent 组件包装在withRouter 函数中:

export default withRouter(CreateContent)

withRouter 将在渲染时将更新的匹配、位置和历史道具传递给包装的组件。

withRouter v5 中的引用:https://v5.reactrouter.com/web/api/withRouter

【讨论】:

  • 感谢您的解释。我认为您的答案是我正在寻找的并尝试将其应用于我的应用程序,但我并没有悄悄地如何使用它。那么我应该创建单独的组件来添加上面的代码还是应该添加上面的代码每个我想使用历史的组件?还是应该将其添加到 App.js 中?你能添加例子吗?谢谢!
  • 我已经更新了我的答案。 @辛迪
  • 我在顶层 (src) 中创建了带有Router.js 的文件,并复制并粘贴了您的代码。想知道如何在 CreateContent.js 中导入它?我在 withRouter.js 和 import {withRouter} from './withRouter' 中添加了export default withRouter,但我仍然错了吗?再次感谢您!
  • 您是否仍然面临问题或已解决? @辛迪
  • 感谢您关注我!我成功了! @Sanket Shah 真的是很棒的解决方案!
【解决方案2】:

你可以在react中以多种方式实现重定向。

1- 只使用 react-router-dom 中的链接

<Link to={"/my-route"} />

2- 你可以使用 react-router-dom 中的 useNavigate

const navigate = useNavigate()
navigate("/my-route")

3- 如果

,您可以简单地使用状态来显示/隐藏组件
const [visibleComponent, setVisibleComponent] = useState('component1')
<Component1 isVisible={visibleComponent === 'component1'} />
<Component2 isVisible={visibleComponent === 'component2'} />
<Component3 isVisible={visibleComponent === 'component3'} />

然后您可以根据您的逻辑更改组件( setVisibleComponent('component2') 以显示第二个组件,依此类推...

【讨论】:

  • so.. 我想像我的例子一样在函数内部使用它。点击按钮后,您将发布您的内容,然后让用户移动到主页。我试过 2. 但它返回 Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 因为我正在使用类组件(我认为..)
  • 是的,你不能在基于类的组件中使用钩子,你可以做的是创建一个按钮组件,使其成为功能组件,这样你就可以使用钩子,然后在其中使用 useNavigate()
猜你喜欢
  • 2018-02-21
  • 2020-02-07
  • 2019-09-05
  • 1970-01-01
  • 2017-04-14
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多