【问题标题】:Re-render array of child components in React after editing the array编辑数组后在 React 中重新渲染子组件数组
【发布时间】: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 中从数组中删除后更改键顺序

【问题讨论】:

    标签: reactjs ecmascript-6 state


    【解决方案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 我确信逻辑正在运行,因为我可以在删除发生后看到数据数组处于状态。
    猜你喜欢
    • 2020-05-01
    • 2018-11-12
    • 2019-06-01
    • 2019-02-26
    • 1970-01-01
    • 2021-06-07
    • 2021-06-19
    • 2018-04-22
    相关资源
    最近更新 更多