使用 onClick 和单选按钮浏览不同的页面 - React.js

Navigating through different pages with onClick & radio buttons - React.js

*使用 react-router-dom 和 react.js

我有两组不同的单选按钮。一组有 2 个按钮,而另一组有 3 个。每当用户单击两个按钮(每组一个)时,我想导航到一个新页面。我们总共有六个不同的结果,因此需要导航到 6 个不同的页面。它似乎工作正常但有一个问题:它仅在我们第二次单击按钮时才有效。示例:单击“消息”和“全局”最初不起作用,也不会执行任何操作,但如果我们单击其他按钮,它就会导航到我们单击的初始按钮集。

有谁知道如何解决这个问题?谢谢。

import { useNavigate } from 'react-router-dom';

export default function DisplayHomeOptions() {
    let navigate = useNavigate();
    const [formData, setFormData] = React.useState({ location: "", selector: "" })

    function handleChange(event) {
        const { name, value, type, checked } = event.target
        setFormData(prevFormData => {
            return {
                ...prevFormData,
                [name]: type === "checkbox" ? checked : value
            }
        })
    }

    function test() {
        return (
            formData.location === "National" && formData.selector === "Polls" ? navigate("/np") :
                formData.location === "Global" && formData.selector === "Questions" ? navigate("/gq") :
                    formData.location === "Global" && formData.selector === "Polls" ? navigate("/gp") :
                        formData.location === "National" && formData.selector === "Messages" ? navigate("/nm") :
                            formData.location === "National" && formData.selector === "Questions" ? navigate("/nq") :
                                formData.location === "Global" && formData.selector === "Messages" ? navigate("/gm") : null
        )
    }


    return (
        <div>
            <fieldset>
                <legend>Option #1</legend>
                <input
                    type="radio"
                    name="location"
                    value="Global"
                    onChange={handleChange}
                    onClick={test}
                />

                <label htmlFor="Global">Global</label>
                <input
                    type="radio"
                    name="location"
                    value="National"
                    onChange={handleChange}
                    onClick={test}
                />
                <label htmlFor="National">National</label>
            </fieldset>

            <fieldset>
                <legend>Option #2</legend>
                <input
                    type="radio"
                    name="selector"
                    value="Messages"
                    onChange={handleChange}
                    onClick={test}


                />
                <label htmlFor="Messages">Messages</label>
                <input
                    type="radio"
                    name="selector"
                    value="Questions"
                    onChange={handleChange}
                    onClick={test}

                />
                <label htmlFor="Questions">Questions</label>
                <input
                    type="radio"
                    name="selector"
                    value="Polls"
                    onChange={handleChange}
                    onClick={test}
                />
                <label htmlFor="Polls">Polls</label>
            </fieldset>
        </div>
    )
}```

问题

问题是 React 状态更新不会立即处理,它们会排入队列并在稍后异步处理。当同时调用 test 函数时,来自 handleChangeformData 状态更新尚不可用。

解决方案

您似乎希望导航行为成为从单选按钮中进行选择的效果。将 test 功能逻辑移动到 useEffect 挂钩中以发出命令式导航。

示例:

export default function DisplayHomeOptions() {
  const navigate = useNavigate();

  const [formData, setFormData] = React.useState({
    location: "",
    selector: ""
  });

  useEffect(() => {
    const { location, selector } = formData;
    switch (true) {
      case location === "National" && selector === "Polls":
        navigate("/np");
        break;

      case location === "Global" && selector === "Questions":
        navigate("/gq");
        break;

      case location === "Global" && selector === "Polls":
        navigate("/gp");
        break;

      case location === "National" && selector === "Messages":
        navigate("/nm");
        break;

      case location === "National" && selector === "Questions":
        navigate("/nq");
        break;

      case location === "Global" && selector === "Messages":
        navigate("/gm");
        break;

      default:
      // ignore
    }
  }, [formData]);

  function handleChange(event) {
    const { name, value, type, checked } = event.target;
    setFormData((prevFormData) => {
      return {
        ...prevFormData,
        [name]: type === "checkbox" ? checked : value
      };
    });
  }

  return (
    <div>
      <fieldset>
        <legend>Option #1</legend>
        <input
          type="radio"
          name="location"
          value="Global"
          onChange={handleChange}
        />

        <label htmlFor="Global">Global</label>
        <input
          type="radio"
          name="location"
          value="National"
          onChange={handleChange}
        />
        <label htmlFor="National">National</label>
      </fieldset>

      <fieldset>
        <legend>Option #2</legend>
        <input
          type="radio"
          name="selector"
          value="Messages"
          onChange={handleChange}
        />
        <label htmlFor="Messages">Messages</label>
        <input
          type="radio"
          name="selector"
          value="Questions"
          onChange={handleChange}
        />
        <label htmlFor="Questions">Questions</label>
        <input
          type="radio"
          name="selector"
          value="Polls"
          onChange={handleChange}
        />
        <label htmlFor="Polls">Polls</label>
      </fieldset>
    </div>
  );
}

一个优化可能是从 locationselector 值声明一个目标路径映射作为键。

const navTarget = {
  National: {
    Messages: "/nm",
    Polls: "/np",
    Questions: "/nq",
  },
  Global: {
    Messages: "/gm",
    Polls: "/gp",
    Questions: "/gq",
  }
}

...

useEffect(() => {
  const { location, selector } = formData;
  if (location && selector) {
    const target = navTarget[location][selector];
    if (target) {
      navigate(target);
    }
  }
}, [formData]);

onClick 事件在 onChange 事件之前触发。为了解决这个问题,您可以将导航移动到 onChange 事件处理程序中。