【问题标题】:How to programatically route in React within a state?如何在状态内以编程方式在 React 中路由?
【发布时间】:2021-01-06 12:50:23
【问题描述】:

我是 React 新手,使用 Zusand 处理全球商店。 在这个特定实例中,我的目标是在找到正确的用户时路由到“RSVP”页面。

场景 A:在数据库中找到用户。路由到新页面

场景 B:在数据库中找不到用户。停留在当前页面并显示错误信息

如果您想在点击时实现这一点,这似乎很简单,但是我找不到任何关于如何在状态内触发它的信息。

我的理解是useHistory可以使用,但是只能在函数内部使用,所以当我尝试在一个状态下使用它时它不起作用。例如。

import create from 'zustand';
import { mountStoreDevtool } from 'simple-zustand-devtools';
import { useHistory } from "react-router-dom";


const useStore = create((set, get) => ({
  guests: [],
  currentGuests: [],
  message: "Please enter your unique password found in your email.",
  returnDatabase: (input) => {
    const guests = get().guests;

    const targetParty = guests.filter((guest) => guest.party === input);
    
    if (targetParty.length !== 0) {
      set({ currentGuests: targetParty });
      const setMessage = "Please enter your unique password found in your email.";
      set({ message: setMessage });

      //I want to programatically redirect here
      let history = useHistory();
      history.push("/rsvp");

    } else {
      const setMessage = "Your password has not been found. Please check your email and try again.";
      set({ message: setMessage });
    }
  
  },
  setStore: (data) => {
    const guestsData = data.guests;
    set({ guests: guestsData });
  },
}));

但是,我收到了这个错误:

Failed to compile
src/store/storeUtil.js
  Line 19:21:  React Hook "useHistory" is called in function "returnDatabase" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter  react-hooks/rules-of-hooks

Search for the keywords to learn more about each error.

我认为这是因为它不在函数中,所以我尝试将它放在单独的组件中:

import create from 'zustand';
import { mountStoreDevtool } from 'simple-zustand-devtools';
import { useHistory } from "react-router-dom";

  export function RsvpButton(){
    let history = useHistory();
  
    function handleClick() {
      history.push("/rsvp");
    }
  
    return (
      {handleClick}
    );
  }


const useStore = create((set, get) => ({
  guests: [],
  currentGuests: [],
  message: "Please enter your unique password found in your email.",
  returnDatabase: (input) => {
    const guests = get().guests;

    const targetParty = guests.filter((guest) => guest.party === input);
    
    if (targetParty.length !== 0) {
      set({ currentGuests: targetParty });
      const setMessage = "Please enter your unique password found in your email.";
      set({ message: setMessage });

      //try to use component here 
      <RsvpButton />

...etc

这只是没有做任何事情/有任何错误。除了 useHistory 之外,我是否应该使用其他方法来路由到 RSVP 页面?还是我在实施中做错了什么?

【问题讨论】:

    标签: javascript reactjs routes state


    【解决方案1】:

    您的按钮组件 RsvpButton 没有创建按钮。

    函数 RsvpButton 的代码应该类似于

    export function RsvpButton () {
        ... 
        return (
            <button onClick={handleClick}>Rsvp</button>
        ) 
    }
    

    这样,handleClick 函数将链接到按钮的onClick 属性,这将使它在单击按钮时运行。

    【讨论】:

    • 嗨 Rituraj,感谢您的回答。我的问题是,我希望它根据逻辑手动触发(即不点击)。如果用户在列表中:触发路由如果用户不在列表中:留在同一页面并显示错误消息我将编辑问题以更清楚。
    【解决方案2】:

    任何有类似问题的人的解决方案:

    为了解决这个问题,我将 useHistory 处理程序放在父组件中 RsvpContainer.js

    import { useHistory } from 'react-router-dom';
        useEffect(() => {
          loadData();
        });
        return (
            <React.Fragment>
                <div className="header">
                    <div className="Bg section-2"></div>
                    <div className="divider"></div>
                    <div className="App section-2">
                        <h3>RSVP.</h3>
                        <h2>Saturday 30 October, 2021</h2>
                        <Input 
                            filter={filter} 
                            setFilter={setFilter}
                            returnDatabaseHandler={returnDatabaseHandler}
                            onUserFound={onUserFoundHandler}
                        />
                            
                    </div>
                </div>
            </React.Fragment>
        )
    

    Input.js

    export function Input({ setFilter, filter, onUserFound }) {
      const isUserFound = useStore((state) => state.isUserFound);
    
      useEffect(() => {
        if (isUserFound) {
          onUserFound();
        }
      }, [isUserFound]);
    
    }
    

    storeUtil.js (zustand global store) - 我在'returnDatabase'中添加了这个

      set({
        message: setMessage,
        isUserFound: true
      });
    

    【讨论】:

      猜你喜欢
      • 2021-09-12
      • 2014-11-10
      • 2020-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-26
      相关资源
      最近更新 更多