如何在此React组件中修复"无法分配给对象的只读属性'样式"?

Tim*_*imo 6 javascript jsx ecmascript-6 reactjs

我正在创建自己的自定义选项卡组件.如果由标签标题组成,每个标题标题都有一个正文部分.单击选项卡标题时,应将相应正文的样式设置为display:block其他所有样式display:none.

由于某些原因,我收到此错误:

无法分配给只读对象的属性"样式"

我知道我不允许手动改变样式属性,因为它似乎是只读的,但我该如何修复/解决这个问题呢?

这是我的代码:

Tabs.js

import React, { Component } from 'react';

class Tabs extends Component {

  constructor() {
    super();
    this.state = {
      activeIndex: 0,
    };
    this.tabHeads = [];
  }

  // Initial composition of tab heads
  componentWillMount() {
    React.Children.map(this.props.children, (el, i) => {
      const tab = el;
      const key = `tabKey${i}`;
      this.tabHeads.push((
        <div role="button" onClick={e => this.onTabClick(e, i)} key={key}>{tab.props.title}</div>
      ));
    });
  }

  // Called when user clicks a tab head
  onTabClick(e, i) {
    this.setState({ activeIndex: i });
  }

  render() {
    // Set display none or block for each tab
    React.Children.map(this.props.children, (el, i) => {
      const tab = el;
      let visibility = 'none';
      if (i === this.state.activeIndex) visibility = 'block';
      const newStyle = Object.assign({}, tab.props.style, { display: visibility });
      tab.props.style = newStyle;
    });

    return (
      <div style={this.props.style}>
        {this.tabHeads}
        {this.props.children}
      </div>
    );
  }
}

export default Tabs;
Run Code Online (Sandbox Code Playgroud)

用法是这样的:

render() {
  const tabStyles = [
    { padding: '20px' }, // Tab 0
    { padding: '20px' }, // Tab 1
  ];

  <Tabs>

    <Tab style={tabStyles[0]} title="Tab1">
      <div>Content 1</div>
    </Tab>

    <Tab style={tabStyles[1]} title="Tab2">
      <div>Content 2</div>
    </Tab>

  </Tabs>
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*icz 7

您尝试更改此行中的属性值:
tab.props.style = newStyle;
props在React中是只读的,您无法手动更改其值.有关更多详细信息,请查看React 文档.
要修复它,您可以使用React.cloneElement哪个允许克隆具有将合并到现有属性的新属性的元素:

render() {
    let childrenWithNewProps = React.Children.map(this.props.children, (el, i) => {
        let visibility = 'none';
        if (i === this.state.activeIndex) visibility = 'block';
        return React.cloneElement(el, {
               style: {
                 display: visibility
               }
           }
        )
    });

    return (
          <div style={this.props.style}>
            {this.tabHeads}
            {childrenWithNewProps}
          </div>
    );
}
Run Code Online (Sandbox Code Playgroud)

  • 答案已更新 - 应在返回的JSX中使用包含克隆元素的数组 (2认同)