React不更新网站。

huangapple go评论77阅读模式
英文:

React doesnt update site

问题

以下是您要翻译的代码部分:

form.jsx

import { useState } from 'react';
import './styles/form.css';
import Tasks from './tasks';

function TaskForm() {
  const initialList = [{task: '做一些事情', done: false}];
  const [tasks, setTasks] = useState(initialList);
  const [input, setInput] = useState('');
  const [validTask, setValidTask] = useState('valid');
  const addTask = () => {
    if(input.length !== 0) {
      setValidTask('valid');
      setTasks([...tasks, {task: input, done: false}]);
      setInput('');
    }
    else {
      setValidTask('invalid');
    }
    console.log(tasks);
  }
  return (
    <>
      <div className='maindiv'>
        <p>任务应用</p>
        <input maxLength={32} value={input} placeholder='添加新任务...' onChange={e => setInput(e.target.value)}/><br />
        <p style={{color: 'red'}} className={validTask}>任务不能为空</p>
        <input type='submit' value='添加任务' onClick={addTask}/>
      </div>
      <Tasks tasks={tasks}/>
    </>
  );
}

export default TaskForm;

tasks.jsx

import { useState } from 'react';
function Tasks(props) {
  const [tasks, setTasks] = useState(props.tasks);
  const deleteTask = (index) => {
    tasks.splice(index, 1);
    setTasks([...tasks]);
  };
  const taskList = props.tasks.map((task, index) => (
    <li key={index}>
      <input type='checkbox' value={task.done} /> 
      {task.task}
      <input type='button' value='删除' onClick={() => deleteTask(index)} />
    </li>
  ));
  return <ul>{taskList}</ul>;
}

export default Tasks;
英文:

I'm making simple todo list in react, and when i delete a task it doesnt update immediately, but when i make a change in input, I don't know why it happens. Tried to change how deleteTask works but i didnt found the solution.

form.jsx

import { useState } from &#39;react&#39;;
import &#39;./styles/form.css&#39;;
import Tasks from &#39;./tasks&#39;;

function TaskForm() {
  const initialList = [{task: &#39;Do something&#39;, done: false}];
  const [tasks, setTasks] = useState(initialList);
  const [input, setInput] = useState(&#39;&#39;);
  const [validTask, setValidTask] = useState(&#39;valid&#39;);
  const addTask = () =&gt; {
    if(input.length !== 0) {
      setValidTask(&#39;valid&#39;);
      setTasks(tasks.push({task: input, done: false}));
      setTasks(tasks);
      setInput(&#39;&#39;);
    }
    else {
      setValidTask(&#39;invalid&#39;);
    }
    console.log(tasks);
  }
  return (
    &lt;&gt;
      &lt;div className=&#39;maindiv&#39;&gt;
        &lt;p&gt;Task app&lt;/p&gt;
        &lt;input maxLength={32} value={input} placeholder=&#39;add a new task...&#39; onChange={e =&gt; setInput(e.target.value)}/&gt;&lt;br /&gt;
        &lt;p style={{color: &#39;red&#39;}} className={validTask}&gt;Task can&#39;t be empty&lt;/p&gt;
        &lt;input type=&#39;submit&#39; value=&#39;Add task&#39; onClick={addTask}/&gt;
      &lt;/div&gt;
      &lt;Tasks tasks={tasks}/&gt;
    &lt;/&gt;
  );
}

export default TaskForm;

tasks.jsx

import { useState } from &#39;react&#39;;
function Tasks(props) {
  const [tasks, setTasks] = useState(props.tasks);
  const deleteTask = (index) =&gt; {
    tasks.splice(index, 1);
    setTasks(tasks);
    
  };
  const taskList = props.tasks.map(task =&gt; (
    &lt;li key={task.id}&gt;
      &lt;input type=&#39;checkbox&#39; value={task.done} /&gt; 
      {task.task}
      &lt;input type=&#39;button&#39; value=&#39;delete&#39; onClick={() =&gt; deleteTask(task.id)} /&gt;
    &lt;/li&gt;
  ));
  return &lt;ul&gt;{taskList}&lt;/ul&gt;;
}

export default Tasks;

答案1

得分: 1

你不能像文档中明确描述的那样在React状态中拼接数组。

使用切片的方法:

const deleteTask = (index) => {
    setTasks(tasks => [...tasks.slice(0, index), ...tasks.slice(index+1)]);
};

或者使用过滤器的方法:

const deleteTask = (index) => {
    setTasks(tasks => [...tasks].filter((_, i) => i === index));
};
英文:

You can't splice arrays in React states as clearly described in the docs

const deleteTask = (index) =&gt; {
    setTasks(tasks =&gt; [...tasks.slice(0, index), ...tasks.slice(index+1)]);
};

or using filter:

const deleteTask = (index) =&gt; {
    setTasks(tasks =&gt; [...tasks].filter((_, i) =&gt; i === index));
};

答案2

得分: 1

你没有更新状态,而是修改状态:

tasks.splice(index, 1);
setTasks(tasks);

根据文档

splice() 方法通过删除或替换现有元素和/或添加新元素 原地 更改数组的内容。

因此,不要创建新的数组引用,而是修改现有的数组引用并将状态设置回同一引用。由于引用未更改,React 不会注意到状态已经“更新”。这就是为什么修改状态会导致此类错误的原因。

应该创建一个新的数组引用,对其进行修改,然后将状态更新为新引用:

let newTasks = [...tasks];
newTasks.splice(index, 1);
setTasks(newTasks);
英文:

You're not updating state, you're mutating state:

tasks.splice(index, 1);
setTasks(tasks);

According to the documentation:

> The splice() method changes the contents of an array by removing or replacing existing elements and/or adding new elements in place.

So instead of creating a new array reference, you're modifying the existing array reference and setting state back to that same reference. Since the reference doesn't change, React doesn't see that the state was "updated". Which is why mutating state leads to bugs like this.

Create a new array reference, modify that, then update state to that:

let newTasks = [...tasks];
newTasks.splice(index, 1);
setTasks(newTasks);

huangapple
  • 本文由 发表于 2023年6月19日 21:43:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76507226.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定