【问题标题】:React Hooks: Cannot assign to read only propertyReact Hooks:无法分配给只读属性
【发布时间】:2020-02-17 01:41:22
【问题描述】:

我正在尝试更新使用 React.createElement() 创建的对象。我要更新的属性是particleCopy.props.style.top。下面是我的代码。

import React, { useState } from 'react';
import './Particles.scss';

export default function Particles() {
  const particleStyle = { color: 'blue', position: 'absolute', top: '0px' };
  const [particle, setParticle] = useState(
    React.createElement('div', { style: particleStyle }, '*')
  );

  const moveParticleDown = (particle, top) => {
    const particleCopy = Object.assign({}, particle);
    particleCopy.props.style.top = top + 'px';
    setParticle(particleCopy);
  };

  return (
    <div className="particles_container">
      <div className="particles">{particle}</div>
      <div className="controls">
        <button onClick={() => moveParticleDown(particle, 10)}>down</button>
      </div>
    </div>
  );
}

我收到以下错误

Uncaught TypeError: Cannot assign to read only property 'top' of object '#&lt;Object&gt;'

【问题讨论】:

    标签: reactjs typescript react-hooks


    【解决方案1】:

    如果您应该在状态中添加元素是否值得推荐,我实际上搜索了互联网。我认为这不是你应该在 React 中实现该行为的方式。好吧,如果它有效,我会保持开放的心态。发现另一个解决此讨论的问题(查看第二条评论):Add element to a state React

    更不用说复制了,成本很高。

    为什么不将位置保存为状态?

    export default function Particles() {
      const particleStyle = { color: 'blue', position: 'absolute', top: '0px' };
      // if ever you need to track other than top
      const [position, setPosition] = useState({top: 0, bottom: 0, left: 0, right: 0});
    
      const moveParticleDown = p => {
        setPosition({top: p});
      };
    
      return (
        <div className="particles_container">
          <div className="particles">
            <div style={...particleStyle, top: `${position.top}px`} /> 
          </div>
          <div className="controls">
            <button onClick={() => moveParticleDown(10)}>down</button>
          </div>
        </div>
      );
    }
    

    【讨论】:

      【解决方案2】:

      您的particleCopy 函数仅创建particle 的浅表副本,这意味着您正在尝试改变particle 指向的对象。您可以查看深度克隆库,或者在 React 中似乎更惯用的方法,将对象扩展到您必须的范围内:

      const particleCopy = {
        ...particle,
        props: {
          ...particle.props,
          style: {
            ...particle.props.style,
            top: top + 'px'
          }
        }
      }
      setParticle(particleCopy);
      

      【讨论】:

      • 感谢它的工作,所以我猜这更多的是一个 javascript 错误,那么没有那么多反应呢?
      • 是的,问题实际上是 Object.assign 不会克隆超过一层的对象。我想从技术上讲这个问题与 React 相关,因为 React 深度冻结了有状态的对象,所以你不会意外地改变它们。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-08
      • 2021-05-10
      • 2020-06-26
      • 2019-12-06
      • 2014-12-04
      • 1970-01-01
      相关资源
      最近更新 更多