输入字段在我输入时失去焦点

问题描述 投票:0回答:1

我正在构建一个 React 应用程序,它使用输入字段允许用户输入菜谱标题,然后,当他们提交表单时,菜谱应添加到 RecipeList 中。

目前,我的代码无法正常工作,因为在输入字段失去焦点之前我只能输入 1 个单词。如果我必须猜测,我会猜测当我输入字母时,表单会以某种方式重新呈现。 我想继续打字而不失去输入焦点。

这是我的代码:

function RecipeApp() {

  const [recipes, setRecipes] = useState(initialRecipes);
  const [recipeInput, setRecipeInput] = useState("");
  const [summaryInput, setSummaryInput] = useState("");
  const [ingredientsInput, setIngredientsInput] = useState([]);
  const [cookTimeInput, setCookTimeInput] = useState("");

  function handleAddRecipe(e) {
    e.preventDefault();
    if (!recipeInput || !summaryInput || !ingredientsInput || !cookTimeInput) {
      alert("Please fill out all fields!");
      return;
    }

    const newRecipe = {
      id: recipes.length,
      title: recipeInput,
      summary: summaryInput,
      ingredients: ingredientsInput.split(",").reduce(
        (acc, ing, idx) => ({
          ...acc,
          [`ingredient${idx + 1}`]: ing.trim(),
        }),
        {}
      ),
      cookTime: parseInt(cookTimeInput, 10),
    };

    setRecipes([...recipes, newRecipe]);
    setRecipeInput("");
    setSummaryInput("");
    setIngredientsInput("");
    setCookTimeInput("");
  }

  function InputForm() {
    return (
      <form onSubmit={handleAddRecipe}>
        <p>Recipe name</p>
        <input
          value={recipeInput}
          onChange={(e) => setRecipeInput(e.target.value)}
        />

        <p>Summary</p>
        <input value={summaryInput} placeholder="Enter a description" />

        <p>Ingredients</p>
        <input
          value={ingredientsInput}
          placeholder="List up to four ingredients, seperated by a comma"
        />

        <p>Cook Time (minutes)</p>
        <input value={cookTimeInput} placeholder="Time in minutes" />

        <button>Add</button>
      </form>
    );
  }

  function RecipeList() {
    return (
      <ul>
        {recipes.map((recipe) => (
          <li key={recipe.id}>
            {recipe.title}
            <button>View</button>
            <button>Delete</button>
          </li>
        ))}
      </ul>
    );
  }

  return (
    <div className="RecipeApp">
      <InputForm />
      <h2>List of recipes:</h2>
      <RecipeList />
    </div>
  );
}
javascript reactjs jsx
1个回答
0
投票

原因:

InputForm 有输入,调用 setState 函数来更新值。 useState 会导致整个功能组件的重新渲染。这会导致您的代码重新渲染完整的 ReceipeApp,其中它返回带有 InputForm 和 ReceipeList 的 JSX。因此,在这里,InputForm 会使用任何输入中键入的每个字母的现有值(食谱、烹饪时间、收据列表等)重新呈现。

解决方案:

InputForm 函数必须位于 ReceipeApp 函数之外。尝试单独拥有每个功能,并在需要时传递 props。

示例:InputForm 可能如下所示

function InputForm() {
const [recipes, setRecipes] = useState([]);
const [recipeInput, setRecipeInput] = useState("");
const [summaryInput, setSummaryInput] = useState("");
const [ingredientsInput, setIngredientsInput] = useState([]);
const [cookTimeInput, setCookTimeInput] = useState("");

function handleAddRecipe(e) {
  e.preventDefault();
  if (!recipeInput || !summaryInput || !ingredientsInput || !cookTimeInput) {
    alert("Please fill out all fields!");
    return;
  }

  const newRecipe = {
    id: recipes.length,
    title: recipeInput,
    summary: summaryInput,
    ingredients: ingredientsInput.split(",").reduce(
      (acc, ing, idx) => ({
        ...acc,
        [`ingredient${idx + 1}`]: ing.trim(),
      }),
      {}
    ),
    cookTime: parseInt(cookTimeInput, 10),
  };

  setRecipes([...recipes, newRecipe]);
  setRecipeInput("");
  setSummaryInput("");
  setIngredientsInput("");
  setCookTimeInput("");
}
return (
  <form onSubmit={handleAddRecipe}>
    <p>Recipe name</p>
    <input
      value={recipeInput}
      onChange={(e) => {setRecipeInput(e.target.value)}}
    />

    <p>Summary</p>
    <input value={summaryInput} placeholder="Enter a description" 
      onChange={(e) => {setSummaryInput(e.target.value)}}/>

    <p>Ingredients</p>
    <input
      value={ingredientsInput}
      placeholder="List up to four ingredients, seperated by a comma"
      onChange={(e) => {setIngredientsInput(e.target.value)}}
    />

    <p>Cook Time (minutes)</p>
    <input value={cookTimeInput} placeholder="Time in minutes" 
      onChange={(e) => {setCookTimeInput(e.target.value)}}/>

    <button type='submit'>Add</button>
  </form>
);

}

注意:将 type="submit" 添加到表单按钮并处理所有输入字段中的 onchange

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.