【问题标题】:Unable to add values to array state React无法将值添加到数组状态 React
【发布时间】:2021-05-31 21:34:47
【问题描述】:

我最近发布了一个关于通过 websocket 发送和接收数据的问题。为了不重复大部分工作,原始问题在这里找到:Socket.io emitting undefined variable React

我已经稍微修改了我的应用程序,以便从服务器接收到的每个 id 都被添加或删除到 disabled 数组中(如果从服务器接收到的 focus 参数为 true,则添加 id,如果不是,则删除它)。这样我就可以根据发送的焦点禁用/启用问题。

我做了三处细微的调整,都在 App.js 文件中

1.将disabled 数组添加到状态

const [disabled, setDisabled] = useState([])

2。在问题中包含disabled 参数

<TextArea
    cols={50}
    helperText="Optional helper text here; if message is more than one line text should wrap (~100 character count maximum)"
    id="text2"
    invalidText="Invalid error message."
    labelText="Text area label"
    placeholder="Placeholder text"
    rows={4}
    onFocus={() => setFocusTrue('text2')}
    onBlur={() => setFocusFalse('text2')}
    disabled={disabled.indexOf('text2')!==-1}
/>

您会注意到,如果 questionId 包含在disabled 数组中(因此禁用问题),disabled 参数将设置为 true,否则为 false

3.将 questionId 添加到disabled 状态数组

useEffect(() => {
    socket.on("message", ({ user, id, focus }) => {
        console.log(user, "clicked on", id, "with focus", focus)
        console.log('adding', id, 'to disabled')
        setDisabled(prevDisabled => [...prevDisabled, id]);
        console.log("disabled:", disabled)
    })
}, [])

现在,我只是将来自服务器的所有 questionId 添加到 disabled 数组中,以便测试它们是否确实被添加。但这是我的问题,disabled 数组始终为空(请参见下面的屏幕截图)。在设置新的disabled 状态之前的控制台日志输出中可以看到id 变量存在,但它没有按预期添加。

编辑: 根据 cmets,我可以看到 disabled 数组实际上正在更新,如果我在渲染之前 console.log(disabled)。但是,如果我对数组应用任何类型的逻辑,就会出现错误。下面是修改后的useEffect,其中包含一些逻辑(本质上是向数组添加或删除一个id)

useEffect(() => {
    socket.on("message", ({ user, id, focus }) => {
      console.log(user, "clicked on", id, "with focus", focus)
      console.log('adding', id, 'to disabled')
      if (focus) {
        console.log('not my user and focus is true')
        setDisabled(prevDisabled => [...prevDisabled, id])
        console.log("disabled after adding", disabled)
      } else {
        let filteredArray = disabled.filter(idToRemove => idToRemove !== id)
        setDisabled({disabled: filteredArray});
      }
      console.log("disabled:", disabled)
    })
  }, [])

当我点击一个文本框时,问题的id 会按预期添加到disabled 数组中,但是当我点击它时,我收到以下错误:

disabled.indexOf 不是函数

这里指的是disabled={disabled.indexOf('text1')!==-1}

【问题讨论】:

    标签: javascript arrays reactjs react-native websocket


    【解决方案1】:

    我认为您的代码很好,如果您在设置后立即尝试 console.log 最重新发送的状态,它不会工作,为什么? setState 是asynchronous,它可能无法像您预期的那样实时工作。

    你真正想尝试的是添加一个 useEffect 并监听 disabled 状态的变化

    useEffect(() => {
        console.log("disabled", disabled);
    }, [disabled]); // since disabled is in the dependency array this hook function will call, every time when the disabled gets updated.
    // so you are so sure the disabled is getting updated correctly
    

    或者只是在渲染之前执行一个简单的console.log(disabled) 并查看。

    我看到你修改的useEffect 版本不正确,应该更正为

    ....
    const filteredArray = disabled.filter(idToRemove => idToRemove !== id)
    setDisabled(filteredArray);
    ....
    

    【讨论】:

    • 那么我本质上会不会有两个不同的 useEffect 函数,一个专门检查您提到的禁用状态的变化,而另一个等待来自 websocket 的消息?
    • 您不必使用useEffect 来监听它的变化
    • 抱歉,我不太确定我是否理解。考虑到socket.on 部分,在这种情况下useEffect 会是什么样子?你是对的,如果我在渲染之前console.log(disabled,我可以看到确实包含了 ID
    • 啊哈,如果您在 console.log 中看到 disabled,您的代码工作正常(disabled 正在正确更新,无需更改任何内容),我告诉您的 useEffect ,只是为了验证disabled 是否正确更新(因为您对它没有更新并且每次都是空的感到困惑?)
    • 好吧,这很有道理。但是如果我想向disabled 数组添加逻辑,我在哪里可以做到这一点?正如您所说,似乎disabled 正在更新,但每当我应用任何逻辑时,它都会出错。我已经编辑了我的问题以演示一个示例。
    猜你喜欢
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 1970-01-01
    • 2018-06-01
    • 2019-03-28
    • 2014-12-17
    • 1970-01-01
    • 2019-11-08
    相关资源
    最近更新 更多