javascript 如何在reactJS中使用Splice方法后重新呈现页面?

wmvff8tz  于 2022-12-17  发布在  Java
关注(0)|答案(4)|浏览(216)

用onClick方法拼接数组后,数据好像被删除了,但是页面没有更新。如何重新渲染或者更新页面来反映这些变化?
Home.js:

import React from "react";
import "./HomeStyles.css";
import HomeData from "./HomeData";

function Home() {
    function handleDelete(id) {
        var index = HomeData.map(function (e) {
            return e.id;
        }).indexOf(id);
        HomeData.splice(index, 1);
    }

    return (
        <>
            <section className="home_section">
                <div className="home_container">
                    {HomeData.map((item) => {
                        return (
                            <div className="Heading_container" key={item.id}>
                                <h1 className="home_heading">{item.heading}    </h1>
                                <button onClick={handleDelete}>Delete</button>
                            </div>
                        );
                    })}
                    
                    <button className="submit_btn">Submit</button>
                </div>
            </section>
        </>
    );
}

export default Home;

数据:

const HomeData = [
    {
        id: 1,
        heading: 'This is first Heading'
    },
    {
        id: 2,
        heading: 'This is Second Heading'
    },
]

export default HomeData;

我试过使用react-router-domhistory中的useNavigate,但没有效果。

q35jwt9p

q35jwt9p1#

也许你可以利用状态,可以使用useState钩子
它将是这样:

import React, {useState} from "react";
import "./HomeStyles.css";
import HomeData from "./HomeData";

function Home() {

    const [data,setData] = useState(HomeData)
    function handleDelete(id) {
        const newData = data.filter((e) => e.id !== id)
        setData(newData)
    }

    return (
        <>
            <section className="home_section">
                <div className="home_container">
[don't forget to use the state here] >>> {data.map((item) => {
                        return (
                            <div className="Heading_container" key={item.id}>
                                <h1 className="home_heading">{item.heading}    </h1>
                                <button onClick={handleDelete}>Delete</button>
                            </div>
                        );
                    })}
                    
                    <button className="submit_btn">Submit</button>
                </div>
            </section>
        </>
    );
}

export default Home;
w8f9ii69

w8f9ii692#

在React函数组件中,你可以使用一个叫做useState的钩子,通过这个钩子你可以获取和设置你想要的数据。

const [data, setData] = useState(homeData);

然而,在React生态系统中,改变状态是一个很大的禁忌,因为它大量实践了不可变性的概念。剪接通过删除或添加元素本身来改变状态。
除了Map和拼接,你可以使用filter和setter。Filter是不可变的,因为它创建了一个浅副本。你想要创建一个浅副本,但是没有id作为参数的项。这将转化为下面的代码:

setData(homeData.filter(home => home.id !== id));

现在,您所要做的就是通过状态“data”进行Map,而不是直接MaphomeData。

e5njpo68

e5njpo683#

问题

在当前的实现中,代码正在改变一个***不属于任何React状态的***部分的对象,因此React不知道需要重新呈现任何内容。
需要牢记的事项:

  1. Array.prototype.splice对其操作的数组执行 * 原地 * 变异。
    splice()方法通过删除或替换现有元素和/或添加新元素in place来更改数组的内容。要访问数组的一部分而不修改它,请参阅slice()
  2. React组件会出于以下三种原因之一重新渲染:
    1.本地组件状态更新排队,组件和子ReactTree重新呈现
    1.更新传递的props值,重新呈现组件和子ReactTree
    1.父组件重新渲染(* 因为状态和/或属性更新 *)

溶液

要正确呈现***和***,请更新HomeData数组,它 * 必须 * 是React组件状态的一部分。更新React状态、所有状态和子状态时,必须是一个***new***对象引用。这是因为React使用了浅引用相等性检查。使用Array.prototype.filter过滤现有数组***和***要 * 普遍得多返回一个新的数组引用。
首页示例:

import React from "react";
import "./HomeStyles.css";
import HomeData from "./HomeData";

function Home() {
  const [homeData, setHomeData] = React.useState(HomeData); // <-- initialize state

  const handleDelete = (id) => {
    setHomeData(data => data.filter(el => el.id !== id)); // <-- filter and return new array
  };

  return (
    <section className="home_section">
      <div className="home_container">
        {homeData.map((item) => ( // <-- map homeData state
          <div className="Heading_container" key={item.id}>
            <h1 className="home_heading">{item.heading}</h1>
            <button
              button="button" // <-- should be explicit with button type
              onClick={handleDelete}
            >
              Delete
            </button>
          </div>
        ))}
                    
        <button
          className="submit_btn"
          type="submit" // <-- should be explicit with button type
        >
          Submit
        </button>
      </div>
    </section>
  );
}

export default Home;
xxls0lw8

xxls0lw84#

应该使用useState挂接更新视图

import React, { useState } from "react"; //imported useState
import "./HomeStyles.css";
import HomeData from "./HomeData";

function Home() {
 const [homeData, setHomeData] = useState(HomeData); //Added here

 function handleDelete(id) {
    const newData = homeData.filter((e) => e.id !== id)
    setHomeData(newData)
}

return (
    <>
        <section className="home_section">
            <div className="home_container">
                {homeData.map((item) => { //changed state here
                    return (
                        <div className="Heading_container" key={item.id}>
                            <h1 className="home_heading">{item.heading}    </h1>
                            <button onClick={handleDelete}>Delete</button>
                        </div>
                    );
                })}
                
                <button className="submit_btn">Submit</button>
            </div>
        </section>
    </>
);
}

export default Home;

相关问题