【问题标题】:Input not re-rendering onChange with hooks输入不使用钩子重新渲染 onChange
【发布时间】:2021-01-31 19:05:48
【问题描述】:

输入并记录输入 e.target.value 时,我得到默认值 + 最后一次击键,但没有重新渲染。我猜 React 没有识别出状态发生了变化,但是我在找出正确的方法来做这件事时遇到了问题。

这是有问题的代码:

  const [text, setText] = useState(task.text);
  console.log(text);

  const handleInputChange = (e) => {
    setText(e.target.value);
  };

  const taskInput = (
    <form>
      <input type='text' value={text} onChange={handleInputChange} />
    </form>
  );

还有完整的文件:

import React, { useContext, useState } from "react";
import { TaskContext } from "../context/TaskState";

const Task = ({ task }) => {
  const { deleteTask } = useContext(TaskContext);
  const { changeStatus } = useContext(TaskContext);

  const taskText = (
    <div
      className='task-text'
      onClick={() => changeStatus({ ...task, done: !task.done })}
      style={task.done ? { textDecoration: "line-through" } : null}
    >
      {task.text}
    </div>
  );

  const [text, setText] = useState(task.text);
  console.log(text);

  const handleInputChange = (e) => {
    setText(e.target.value);
  };

  const taskInput = (
    <form>
      <input type='text' value={text} onChange={handleInputChange} />
    </form>
  );

  const [option, setOption] = useState(taskText);

  return (
    <div className='task-container'>
      <button className='task-edit' onClick={() => setOption(taskInput)}>
        edit
      </button>
      <button className='task-delete' onClick={() => deleteTask(task.id)}>
        x
      </button>
      {option}
    </div>
  );
};

export default Task;

我正在为应用程序的其余部分和减速器使用全局状态。

【问题讨论】:

  • 首先我建议不要将元素保持在状态作为选项。使选项成为布尔值或[option,...]=useState('taskText') 之类的原语。然后点击更改它。有条件地渲染{ option === 'taskText' ? taskText: taskInput}。也可以制作 taskText 和 taskInout 函数。
  • @kimobrian254 感谢您的帮助!我将选项设置为布尔值,并更改了 onClick 事件,但是当我创建 taskText 和 taskInput 函数时出现错误:index.js:1 Warning: Functions are not valid as a React child. 当我有条件地尝试将它们呈现为组件 ,onClick 事件停止工作,但反应呈现 。在我将它们转换为函数之前发生了同样的事情。
  • 您不渲染函数名称,而是渲染调用(返回值),因此您渲染 {taskText} 而不是 {taskText()}。然后,由于您将 option 设为布尔值,因此请让您的 onClick 像 onClick={() =&gt; setOption(false)} 一样使用它。它首先呈现 taskText(假设选项默认为 true const [option, setOption] = useState(true);),当您单击它时呈现 taskInput,因为选项更改为 false 所以 {option ? taskText: taskInput} 应该按预期工作 @Aleksandar Andonovic
  • 不客气,我将不胜感激。
  • 没关系,不客气

标签: reactjs input react-hooks onchange use-state


【解决方案1】:

问题是我在 jsx 中传递选项的方式。

我将选项状态设为布尔值,将 taskText 和 taskInput 转换为函数,并在 jsx 内有条件地传递选项。

import React, { useContext, useState } from "react";
import { TaskContext } from "../context/TaskState";

const Task = ({ task }) => {
  const { deleteTask } = useContext(TaskContext);
  const { changeStatus } = useContext(TaskContext);

  const taskText = () => {
    return (
      <div
        className='task-text'
        onClick={() => changeStatus({ ...task, done: !task.done })}
        style={task.done ? { textDecoration: "line-through" } : null}
      >
        {task.text}
      </div>
    );
  };

  const [text, setText] = useState(task.text);
  console.log(text);

  const handleInputChange = (e) => {
    setText(e.target.value);
  };

  const taskInput = () => {
    return (
      <form>
        <input type='text' value={text} onChange={handleInputChange} />
      </form>
    );
  };

  const [option, setOption] = useState(true);

  return (
    <div className='task-container'>
      <button className='task-edit' onClick={() => setOption(!option)}>
        edit
      </button>
      <button className='task-delete' onClick={() => deleteTask(task.id)}>
        x
      </button>
      {option ? taskText() : taskInput()}
    </div>
  );
};

export default Task;

【讨论】:

    【解决方案2】:

    请尝试使用依赖text 将您的taskInput 值包装在useMemo 中,因为当您在重新渲染期间将JSX 存储为变量时,它们会引用先前的值,因为他们不知道所使用的变量的值已更改。

     import React, { useMemo, useContext, useState } from "react";
     
     const taskInput = useMemo(() => (
        <form>
          <input type='text' value={text} onChange={handleInputChange} />
        </form>
     ), [text]);
    

    【讨论】:

      【解决方案3】:

      我认为,您输入的onChange 可能会导致此错误。尝试替换这个:

      onChange={handleInputChange}
      

      用这个:

      onChange={(e) => handleInputChange(e)}
      

      e 对象可能未传递给您的方法。

      【讨论】:

        猜你喜欢
        • 2019-04-18
        • 1970-01-01
        • 1970-01-01
        • 2020-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多