编辑数组后在 React 中重新渲染子组件数组

Posted

技术标签:

【中文标题】编辑数组后在 React 中重新渲染子组件数组【英文标题】:Re-render array of child components in React after editing the array 【发布时间】:2018-06-29 12:49:10 【问题描述】:

我有这样的父组件状态的数据:

data=[
            key:0,name="abc",value="123",
            key:1,name="def",value="456",
            key:2,name="ghi",value="789"
     ]

在我的反应组件中,我将子组件称为父组件的返回部分中的列表,如下所示。

class MyApp extends React.Component
  constructor(props) 
    super(props);
     this.state = 
      record=
        name="",
        timestamp="",
        data =[
          key:0,name="abc",value="123",
          key:1,name="def",value="456",
          key:2,name="ghi",value="789"
        ]
    
    this.deleteFromStateArray=this.deleteFromStateArray.bind(this);
  

  deleteFromStateArray(key)
    let oldData = [...this.state.record.data];
    let newData= [];
    oldData.map(function (record, i) 
      if (record.key != key) 
        newData.push(record);
      
    )
    newData.map(function (record, i) 
      newData[i].key = i + 1
    )
    this.setState( record: Object.assign(, this.state.record,  data: newData ), );
  
  render() 

  return(
    
      this.state.data.map((record,index) => 
             <Child key=record.key
              id=record.key
              name=record.name
              value=record.value
              onDelete=this.deleteFromStateArray />
    
  )
  

我正在像这样在子组件中调用 onDelete() <button onClick=this.props.onDelete(this.state.id) /> \\ I am initializing id as key in state inside constructor in child

我的问题是,当我在子类中调用 onDelete 时,我可以在函数中正确删除 key=1 的 obj,但无法正常重新渲染。

我的意思是状态设置正确,数据 1 中只有 2 个项目,key=0,其他项目 key=2。但我在 GUI 中看到的是 2 个子组件 1 的键为 0,第二个子组件的键 = 1,这在状态数据中目前不存在。

谁能帮我正确地重新渲染数据?

我还想在 setState 中从数组中删除后更改键顺序

【问题讨论】:

【参考方案1】:

React 使用key 来判断集合中的元素是否需要重新渲染。键应该是唯一的常量。在您的方法中,您正在更改记录的 key 属性,这可能会导致所描述的错误。

此外,您可以使用简单的filter 调用替换所有代码,如下所示:

this.setState(oldState => ( 
    record: 
        ...oldState.record, 
         
            data: oldState.record.data.filter(item => item.key !== key)
        
    
);

还值得一提的是,您应该使state 尽可能平坦,以简化所需的逻辑。在您的情况下,删除 record 并将其保留如下将是一个好主意:

this.state = 
    name: "",
    timestamp: "",
    data: [
      key:0,name: "abc",value: "123",
      key:1,name: "def",value: "456",
      key:2,name: "ghi",value: "789"
    ]

【讨论】:

这是什么语法。由于我是新手,我可以获取有关它正在做什么的详细信息 好的,所以我没有像你那样通过`map`和push创建新数组,而是使用了filter;然后我修改了你的setState 以确保它在当前状态下工作 - 更多信息在这里:reactjs.org/docs/react-component.html#setstate 这种语法设置状态是否仅适用于 JS 文件(我的是 JSX),因为我在 Visual Studio 代码中遇到错误,例如 [js] Property assignment expected. 【参考方案2】:

我不确定这是否真的适合你,但 deleteFromStateArray 的函数声明在 render 函数内。

我认为你的组件应该是这样的:

class MyApp extends React.Component
  constructor(props) 
    super(props);

    this.state = 
      record=
        name="",
        timestamp="",
        data =[
          key:0,name="abc",value="123",
          key:1,name="def",value="456",
          key:2,name="ghi",value="789"
        ]
    
    this.deleteFromStateArray=this.deleteFromStateArray.bind(this);
  

  deleteFromStateArray(key)
    let oldData = [...this.state.record.data];
    let newData= [];
    oldData.map(function (record, i) 
      if (record.key != key) 
        newData.push(record);
      
    )
    newData.map(function (record, i) 
      newData[i].key = i + 1
    )
    this.setState( record: Object.assign(, this.state.record,  data: newData ), );
  
  render() 
    return(
      
        this.state.record.data.map((record,index) => 
          <Child key=record.key
            id=record.key
            onDelete=this.deleteFromStateArray />
      
    )
  

【讨论】:

我不好,实施的方式就是这样。我会在我的问题中纠正我的问题。但问题依旧 您删除数据的方式一定有问题。如果您可以添加那段代码,那么我可以进一步帮助您。 当然,1 分钟。 我已经添加了相同的内容,但是使用 react chrome extn 我确信逻辑正在运行,因为我可以在删除发生后看到数据数组处于状态。

以上是关于编辑数组后在 React 中重新渲染子组件数组的主要内容,如果未能解决你的问题,请参考以下文章

重新渲染 Reactjs 数组组件

React 功能组件在重新挂载后停止渲染状态更改

React 功能组件中状态更改后组件未重新渲染

为啥在 React 中,当父组件重新渲染时子组件不会重新渲染(子组件没有被 React.memo 包裹)?

如何在状态更改(父)reactjs时重新渲染子组件

更改数组中的一个状态会导致在 React Hooks 中重新渲染整个循环生成的自定义组件