简体   繁体   中英

React hooks setter doesn't trigger rerender after array splice

I have a parent component like this:

import React from "react";
import Test from "./Test";

function App() {
    const [configs, setConfigs] = React.useState([1, 2, 3])
    return (
        <div>
            {configs.map(((oneConfig, index) =>
                    <Test
                        config={oneConfig}
                        remove={() => {
                            configs.splice(index, 1);
                            setConfigs(configs);
                            console.log(222)
                        }}
                    />))
            }
        </div>
    );
}

export default App;

and the Test component is like this

export default function Test(props) {
    return(
        <div style={{border: "solid 1px", margin: "5px"}}>
            <p>This is config {props.config}</p>
            <a href="/" onClick={() => props.remove()}>delete config{props.config}</a>
        </div>
    )
}

I wish that when I click "delete config [i]" a tag, the corresponding div will be removed, but it isn't happening that way.

After setting a breakpoint in the parent component at the beginning of the function and console line, I found out that after executing setConfigs method, the parent component isn't re-rendering.

Any idea why this is so and how can I achieve my goal of removing an element from configs ?

The problem's in the remove prop:

configs.splice(index, 1);

splice mutates the configs state, and mutating state directly in React is a no-no.

Try rewriting your remove prop like so:

remove={() => setConfigs(prev => {
  let left = prev.slice(0, index);   // Everything before configs[index]
  let right = prev.slice(index + 1); // Everything after configs[index]
  return [...left, ...right];
})}

This will set the configs state equal to the previous state without the oneConfig whose delete button you clicked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM