将prop动态添加到React组件数组中的last元素

时间:2017-12-22 09:38:44

标签: javascript reactjs

这个问题我到处搜索但是我找不到分辨率,因为我无法编辑道具对象。

所以这就是到目前为止所做的工作。我们有一个菜单。在这个菜单中,我们有子部分。目前我们实现了这样的目标:

const firstSectionItems = [];
const secondSectionItems = [];
firstSectionItems.push(
  <MenuItem
    onClick={() => {}}
  />,
  <MenuItem
    onClick={() => {}}
  />,
  <MenuItem
    onClick={() => {}}
    sectionEnd
  />
);
secondSectionItems.push(
  <MenuItem
    onClick={() => {}}
  />,
  <MenuItem
    onClick={() => {}}
  />,
  <MenuItem
    onClick={() => {}}
    sectionEnd
  />
);

const items = [...firstSectionItems, ...secondSectionItems];

sectionEnd prop在菜单项后添加一个分隔符,以在菜单中分割各个部分。但是,如果有人添加了菜单项呢?他们必须确保他们移动部分和道具。我想要做的是将此sectionEnd添加到每个数组的最后一个元素中的组件。这可能吗?如果是这样,怎么样?

5 个答案:

答案 0 :(得分:2)

在我看来最好使用数组然后使用.map并管理数组中的对象(plain)作为描述来构建项目:

let firstItems = [{ onclick: () => {}},{ onclick: () => {}}];

然后,在JSX中:

{ firstItems.map((item, index) => (
    <MenuItem
       onClick={item.onClick}
       sectionEnd={index === firstItems.length - 1} 
   />
  ))
}

因此,您可以使用简单的对象和属性数组而不是实例化的JSX元素来更改属性。

答案 1 :(得分:1)

您可以为每个菜单项添加一个键,并拥有一个数组lastItems,该数组将包含状态中相应部分中最后添加的项的键。然后在渲染每个项目时,您可以通过检查该密钥是否包含在lastItems中来添加分隔符。

答案 2 :(得分:1)

为什么不使用HOC?通过这种方式你可以,只需保持你的MenuItem组件清洁,这样HOC只需要知道当前数组的大小和迭代的当前索引,所以你有类似的东西

const WithSectionEndAtLastItem = (props ) => { const {size, index, ...menuProps} = props;
const isLastItem = size - 1 === index;
return <MenuItem {...menuProps} sectionEnd={isLastItem} \>};

因此,当迭代元素时会执行类似

的操作
const size = firstItems.length;
const currentSection = firstItems.map((props , index) => <WithSectionEndAtLastItem {...props} index={index} size{size} \>);
return currentSection;

应该这样做。

我希望你觉得它很有用。

答案 3 :(得分:0)

我会动态创建一个菜单并跟踪最后一个元素。这就是我的意思:

class List extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      items: ['I', 'like', 'SO'],
      item: '',
      last: 2
    }
    this.add = this.add.bind(this);
    this.change = this.change.bind(this);
  }
  change(e){
    this.setState({
        [e.target.name]: e.target.value
    })
  }
  add(){
    const last = this.state.items.length;
    this.setState({
        items: [...this.state.items, this.state.item],
      last,
      item: ''
    })
  }

  render(){
    return (
      <div>
        <ul>
          {this.state.items.map((item, i) =>
            <li key={item}>
              {item}
              // here you can pass props only to the last element
              // i just print it as the last element   
              {this.state.last === i ? ' - Last' : ''}
            </li>)
          }

        </ul>
        <input name="item" type="text" value={this.state.item} onChange={this.change}/>
        <button onClick={this.add}>Add new</button>
      </div>
    )
  }
}

ReactDOM.render(
  <List />,
  document.getElementById('container')
);

工作example

答案 4 :(得分:0)

也许你应该以更具表现力的方式看待它:

const firstSectionItems = [
  <MenuItem onClick={() => {}} />,
  <MenuItem onClick={() => {}} />,
  <MenuItem onClick={() => {}} />,
];
const secondSectionItems = [
  <MenuItem onClick={() => {}} />,
  <MenuItem onClick={() => {}} />,
  <MenuItem onClick={() => {}} />,
];

const items = [...firstSectionItems, <MenuDivider />, ...secondSectionItems];

更好的是,您可以创建一个MenuSection组件来包装分隔符行为:

const MenuSection = ({ items }) => ([
  ...items,
  <MenuDivider />,
]);

const menu = [
  <MenuSection items={firstSectionItems} />,
  <MenuSection items={secondSectionItems} />,
];