在使用Redux渲染时为组件分配唯一ID

时间:2016-09-09 23:25:31

标签: javascript reactjs redux react-redux

下午好,星期五快乐,

我最近开始学习如何使用Redux作为管理我的应用程序中的状态的方法,到目前为止我喜欢它,但是我无法动态地将道具分配给父组件的子项。

以下是我正在使用的内容,有孩子的基本父母情景:

<Layout>
  <Child />
  <Child />
  <Child />
</Layout>

我希望每个孩子都有一个唯一身份证明,因此第一个孩子的childProps.id1,第二个孩子为2,依此类推。

这里首先是我想在渲染组件时触发的assignId函数:

export function assignId(number){
  return{
    type: "ASSIGN",
    payload: number
  }
}

以下是监听此功能的reducer:

export default function reducer(state={

            id: 0

        }, action){

      switch (action.type){
        case "ASSIGN": {
          return {...state, id: action.payload}
        }
      }

  return state

}

最后是<Child />组件本身:

import React from "react";

import { activeBox, beginSession, unselect, assignId } from '../actions/boxActions'

export default class Child extends React.Component {

  componentWillMount(){
    var i = 1

    this.props.dispatch(assignId(i));

    i++

  }

  render(){

    return (
    <div className="box"></div>
    )
  }
}

componentWillMount有效。我var i = 1为我childProps.id组件的所有设置<Child />为1。简单地说,我如何根据childProps.id父级中的顺序创建一个使每个<Child />组件的每个<Layout />唯一的函数?任何和所有的帮助表示赞赏。

周末愉快

3 个答案:

答案 0 :(得分:5)

我认为你在零价值方面增加了复杂性。 DOM元素的id属性肯定是唯一的,因此您处于正确的轨道上,但是

  • 在React中,你不会按照他们的ID来管理元素;请改为references to corresponding DOM elements
  • 生成全局唯一标识符的代价是维护该生成函数,
  • 如果您计划从某个地方获得任意数量的Child个组件并从可迭代中反映出来,为什么不使用Array#map

所以

render() {
  const childElements = [1, 2, 3];

  return (
    <Layout>
      <Child id="1" />
      <Child id="2" />
      <Child id="3" />
    </Layout>
  );
}

变成

render() {
  const childElements = [1, 2, 3];

  return (
    <Layout>
      {childElements.map((id, index) => (
        <Child
          key={index}
          id={id} />
      ))}
    </Layout>
  );
}

从您的代码中,我可以看到您想要分配一个操作来分配带有ID的元素,而该ID甚至不存储在任何地方。如果它确实没有被存储和用于任何目的,则不需要它。

React的一般规则是简单而不复杂。您拥有数据,您可以使用组件(以及它们形成的层次结构)将这些数据反映到DOM中,以及它。如果您需要收听DOM事件,请使用onClickonChange和其他props that are bound to DOM event listeners,以及它。一旦你想使用一个与DOM一起使用的lib,试着坚持使用ref而不是id s,因为那些保证引用现有的DOM元素,id引用可能导致无处可去正在更新组件。

答案 1 :(得分:5)

与其他人所说的相反,将ID分配给商店中的数组项是很有意义的。渲染它们时,您可以将此ID作为key道具传递给每个子组件。当您插入,删除或重新排序数组项时,这开始很有意义。 React将使用此键来帮助它找到与数组项匹配的正确组件。当商店项目索引发生变化时,这可以加速渲染。

这就是key道具存在的原因,也是你不应该简单地使用项目索引的原因。索引与身份不同。

现在,要生成并存储这样一个唯一ID,请执行以下操作:

let nextId = 0;

function addItem(item) {
  return {
    type: 'ADD_ITEM',
    payload: {
      ...item, 
      id: nextId++
    }
  };
}

function reducer(state = [], action) {
  switch action.type {
    case 'ADD_ITEM':
      return [...state, action.payload]
      break; 
    default:
       return state; 
  }
}

然后,您可以将此ID分配给每个孩子的关键支柱。它对于会话来说是独一无二的,而且您可能需要它。如果没有,您可以生成您喜欢的任何其他ID,例如GUID。在任何情况下,重要的是您希望ID从一开始就是项目的一部分,并且ID不是也不应该分配给组件,而是分配给组件将要显示的项目。该组件假定商店中找到的商品的标识,而不是相反。

答案 2 :(得分:1)

在父级别,将您的孩子ID放在数组中,循环播放,并将id指定为孩子的道具。

像这样的东西

<Layout>
  {childrenIds.map((i) => { return <Child id={i} />} )}
</Layout>

我希望有帮助