gpt4 book ai didi

reactjs - useState 钩子(Hook)是否改变了状态的值

转载 作者:行者123 更新时间:2023-12-04 10:59:47 25 4
gpt4 key购买 nike

我刚开始 React,在这个项目列表教程中,我有一些关于更新项目状态的问题。另外,我正在使用功能组件。所以在 app.js

const [items, setItems] = useState([
{
id: 1,
title: 'Banana',
bought: false
},
...
])

然后我在 app.js 中有一个函数可以在我选中一个框时将购买的内容更新为 true 或 false
// The id is passed in from Item.js down below
const markBought = (id) => {
setItems(
items.map(
item => {
if (item.id === id) {
/// If bought is false, checking it will make it true and vice versa
item.bought = !item.bought; // (1)
}
return item; // (2)
})
);
};
return (
<div className="App">
<Items items={items} markBought={markBought}></Items>
</div>
);


老师说我们正在使用一种叫做组件钻孔的东西。所以在Items.js中,我们通过映射每一个item来一个一个的展示出来,但是我觉得没必要展示出来。

最后在 Item.js
<input type="checkbox" onChange={() => props.markBought(props.item.id)} />
{props.item.title}

该应用程序运行良好,但对我来说有点困惑。所以:
  • 在app.js中,当我们更改购买状态后,我们是不是也需要退货,就像条件为假时退货一样?为什么只有在错误的时候才退货,而在正确的时候我们只更改而不退货?
  • 我读到 map 不会修改数组,所以 markBought 函数应该创建一个新的 items 数组,已经修改了买的,但是这个数组会发生什么,React 怎么知道将这个“ Prop ”到 item.js,而不是我硬编码的那些?

  • 抱歉,如果这有点长,任何帮助将不胜感激。谢谢阅读

    最佳答案

    您正在改变 map 中的项目,如果您将 Item 组件优化为纯组件,那么该组件将不会因为突变而重新渲染。请尝试以下操作:

    //use useCallback so marBought doesn't change and cause
    // needless DOM re renders
    const markBought = useCallback(id => {
    setItems((
    items //pass callback to the setter from useState
    ) =>
    items.map(
    item =>
    item.id === id
    ? { ...item, bought: !item.bought } //copy item with changed value
    : item //not this item, just return the item
    )
    );
    }, []);

    这是一个完整的例子:

    const { useCallback, useState, useRef, memo } = React;
    function Items() {
    const [items, setItems] = useState([
    {
    id: 1,
    title: 'Banana',
    bought: false,
    },
    {
    id: 2,
    title: 'Peach',
    bought: false,
    },
    ]);
    const toggleBought = useCallback(id => {
    setItems((
    items //pass callback to the setter from useState
    ) =>
    items.map(
    item =>
    item.id === id
    ? { ...item, bought: !item.bought } //copy item with changed value
    : item //not this item, just return the item
    )
    );
    }, []);
    return (
    <div>
    {items.map(item => (
    <Item
    key={item.id}
    item={item}
    toggleBought={toggleBought}
    />
    ))}
    </div>
    );
    }
    //use memo to make Item a pure component
    const Item = memo(function Item({ item, toggleBought }) {
    const renderedRef = useRef(0);
    renderedRef.current++;
    return (
    <div>
    <div>{item.title}</div>
    <div>bought: {item.bought ? 'yes' : 'no'}</div>
    <button onClick={() => toggleBought(item.id)}>
    toggle bought
    </button>
    <div>Rendered: {renderedRef.current} times</div>
    </div>
    );
    });

    //render the application
    ReactDOM.render(<Items />, document.getElementById('root'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
    <div id="root"></div>


    这是一个损坏的示例,其中您对项目进行了变异,即使状态确实发生了变化,也不会看到重新渲染:

    const { useCallback, useState, useRef, memo } = React;
    function Items() {
    const [items, setItems] = useState([
    {
    id: 1,
    title: 'Banana',
    bought: false,
    },
    {
    id: 2,
    title: 'Peach',
    bought: false,
    },
    ]);
    const toggleBought = useCallback(id => {
    setItems((
    items //pass callback to the setter from useState
    ) =>
    items.map(
    item =>
    item.id === id
    ? ((item.bought = !item.bought),item) //mutate item
    : item //not this item, just return the item
    )
    );
    }, []);
    return (
    <div>
    <div>
    {items.map(item => (
    <Item
    key={item.id}
    item={item}
    toggleBought={toggleBought}
    />
    ))}
    </div>
    <div>{JSON.stringify(items)}</div>
    </div>
    );
    }
    //use memo to make Item a pure component
    const Item = memo(function Item({ item, toggleBought }) {
    const renderedRef = useRef(0);
    renderedRef.current++;
    return (
    <div>
    <div>{item.title}</div>
    <div>bought: {item.bought ? 'yes' : 'no'}</div>
    <button onClick={() => toggleBought(item.id)}>
    toggle bought
    </button>
    <div>Rendered: {renderedRef.current} times</div>
    </div>
    );
    });

    //render the application
    ReactDOM.render(<Items />, document.getElementById('root'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
    <div id="root"></div>

    关于reactjs - useState 钩子(Hook)是否改变了状态的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58893808/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com