【问题标题】:react hooks: useState nested other useState, setState is not working?反应钩子:useState嵌套了其他useState,setState不起作用?
【发布时间】:2020-09-28 01:56:14
【问题描述】:

我编写了使用 react useHooks 动态添加文本的示例。并使用 useState 进行嵌套。 但是,有一个问题,setState 不起作用?

当我点击文本时,组件中的setState不生效(通常是在当前点击的文本上添加一个类,在其他文本上删除该类),怎么办?

下面是具体代码链接:

https://codesandbox.io/s/nifty-sky-z0p9w?file=/src/App.js

谢谢!

【问题讨论】:

  • 兄弟,你指的是cellList状态吗?
  • React 功能组件非常混乱,所有正常的 Javascript 逻辑,关闭状态都消失了。

标签: javascript reactjs react-hooks


【解决方案1】:

您的代码中的问题是:

    const [activeItem, setActiveItem] = useState(null);

您在App 级别定义它。而且您期望这将在 TableCel 中工作,而在另一个具有自己状态的组件中。

更好的方法是将TableCel 组件从App 外部取出并在那里使用状态。如果您需要在 App 内部使用,则也将 activeItemssetActiveItem 作为道具传递。

代码如下:

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

export default function App() {
  const [activeItem, setActiveItem] = useState(null);

  const TableCel = (props) => {
    const { title } = props;

    return <div>{title}</div>;
  };
  const cell = [
    {
      key: 1,
      header: <TableCel id={1} title={"Header"} />,
      render: (cvm) => (
        <>
          <p>--</p>
        </>
      )
    },
    {
      key: 2,
      header: <TableCel id={2} title={"Header"} />,
      render: (cvm) => (
        <>
          <p>--</p>
        </>
      )
    },
    {
      key: 3,
      header: <TableCel id={3} title={"Header"} />,
      render: (cvm) => (
        <>
          <p>--</p>
        </>
      )
    },
    {
      key: 4,
      header: <TableCel id={4} title={"Header"} />,
      render: (cvm) => (
        <>
          <p>--</p>
        </>
      )
    },
    {
      key: 5,
      header: <TableCel id={5} title={"Header"} />,
      render: (cvm) => (
        <>
          <p>--</p>
        </>
      )
    }
  ];
  const [cellList, addCells] = useState(cell);

  const [count, setCount] = useState(6);

  // console.log(cellList);

  const addCell = (value) => {
    const _cell = {
      key: value,
      header: <TableCel title="Header" id={value} />,
      render: (cvm) => (
        <>
          <p>--</p>
        </>
      )
    };
    addCells([...cellList, _cell]);
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <button
        onClick={() => {
          setCount(count + 1);
          addCell(count + 1);
        }}
      >
        add li
      </button>
      <div>
        {cellList
          .filter((cell) => cell.key < 60)
          .map((filteredPerson, index) => (
            <li
              key={index}
              onClick={() => {
                setActiveItem(filteredPerson.key);
              }}
              className={filteredPerson.key === activeItem ? "cel-active" : ""}
            >
              {filteredPerson.header}
            </li>
          ))}
      </div>
    </div>
  );
}

这里是演示:https://codesandbox.io/s/morning-cookies-8eud6?file=/src/App.js:0-2086

【讨论】:

  • 谢谢,我想给当前点击的文本添加一个类,并删除其他文本上的类,我该怎么做?
  • 我认为您实际上不需要在 TableCel 中移动逻辑。仅保留 ui 部分。也更新了我的代码和沙箱。请再次检查
  • 谢谢,对我很有用。
  • 嗨舒巴姆。现在我有一个与上面几乎相似的场景,但是使用现有的组件。如何使用 setState 到 activeItem 状态已经改变。我想制作效果单击表头添加类并删除其他表头上的类。我该怎么做,你能帮帮我吗,谢谢。这是我的代码:codesandbox.io/s/broken-haze-scosm?file=/index.tsx
  • 嗨 Janily 无法使用代码和框链接。可以更新吗?
【解决方案2】:

它不起作用的原因是因为您在函数内部访问 activeItem 状态的值。不建议访问函数内部的状态,因为即使状态已更新,它也始终具有初始值。这就是 &lt;TableCel&gt; 不重新渲染的原因,因为它不知道 activeItem 状态已经改变。

我建议您只访问组件的 useEffect()useCallback()useMemo()return 语句内部的状态。

例如:

function App() {
  const [state, setState] = useState('initial Value')

  function someFunction(){
    // It's not recommended to access the state inside of this function
    // cause the value of the state will always be ('initial Value')
    // even if the state were updated
    console.log(state)
  }

  useEffect(()=>{
    // It's good if you access the value of the state here
    // It will be assured it will always have the updated value
    console.log(state)
  },[state]) 

  return (
    // You can also access the value of the state inside return statement        
    <>
    {console.log(state)}
    <SomeComponent props={state}/>
    </>
  )
}

解决方案:

使用上下文挂钩传递 activeItem 的状态。这样 将真正知道每次 activeItem 状态的变化。

看看这个沙盒链接中的代码我是否使用上下文挂钩来解决问题

https://codesandbox.io/s/quiet-star-zo4ej?file=/src/App.js

【讨论】:

  • 谢谢,对我很有用。
  • 嗨 Rehan,现在我有一个与上面几乎相似的场景,但是使用现有的组件。如何使用 setState 到 activeItem 状态已经改变。我想制作效果单击表头添加类并删除其他表头上的类。我该怎么做,你能帮帮我吗,谢谢。这是我的代码:codepen.io/janily/pen/xxObWVZ
猜你喜欢
  • 2021-04-10
  • 2021-05-26
  • 2021-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-06
  • 1970-01-01
相关资源
最近更新 更多