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

m00*_*aca 1 javascript reactjs redux react-redux

下午好,星期五快乐,

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

以下是我正在使用的基本父母与子女情景:

<Layout>
  <Child />
  <Child />
  <Child />
</Layout>
Run Code Online (Sandbox Code Playgroud)

我希望每个孩子都有一个独特的id,所以childProps.id对于第一个孩子来说1,第二个孩子就是这样2,依此类推.

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

export function assignId(number){
  return{
    type: "ASSIGN",
    payload: number
  }
}
Run Code Online (Sandbox Code Playgroud)

这是reducer监听这个功能:

export default function reducer(state={

            id: 0

        }, action){

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

  return state

}
Run Code Online (Sandbox Code Playgroud)

最后<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>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

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

周末愉快

ris*_*hat 5

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

  • 在React中,您不会按ID来管理元素; 看一下对相应DOM元素的引用,
  • 生成全局唯一标识符是以维护该生成函数为代价的
  • 如果您打算Child从某个地方获得任意数量的组件并从迭代中反映出来,为什么不使用Array#map

所以

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

  return (
    <Layout>
      <Child id="1" />
      <Child id="2" />
      <Child id="3" />
    </Layout>
  );
}
Run Code Online (Sandbox Code Playgroud)

变成

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

  return (
    <Layout>
      {childElements.map((id, index) => (
        <Child
          key={index}
          id={id} />
      ))}
    </Layout>
  );
}
Run Code Online (Sandbox Code Playgroud)

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

React的一般规则是简单而不复杂.你有数据,你使用组件(以及它们形成的层次结构)将这些数据反映到DOM中,就是这样.如果你需要听DOM事件,你可以使用onClick,onChange而其他绑定到DOM事件侦听器的道具,这就是它.一旦你想使用一个与DOM一起使用的lib,试着坚持使用ref而不是ids,因为它们保证引用现有的DOM元素,并且引用id可能导致组件被更新时无处可去.


DDS*_*DDS 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; 
  }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 使用全局变量并不总是一件可怕的事情。请注意,即使应用程序的多个部分使用此功能,也不会发生冲突,因为 ID 仍然是唯一的。此外,将这个变量放在一个闭包中是微不足道的,所以它不再是全局的。尽管如此,它仍然会发挥相同的作用。从状态派生 ID 是可行的,但请注意 ID 应该是项目创建操作的一部分,以便保留可重玩性。无论如何,请查看 Dan Abramov 的 todo 示例,看看他也使用了全局变量。https://github.com/reactjs/redux/blob/master/examples/todos/src/actions/index.js (2认同)