从React.js中的递归渲染组件更新状态 [英] Updating state from recursively rendered component in React.js

查看:68
本文介绍了从React.js中的递归渲染组件更新状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从递归呈现的组件中更新处于React状态的深层嵌套对象.这些项目看起来像这样,可以动态嵌套:

I am in need of updating deeply nested object in a React state from a recursively rendered component. The items look like this and can be nested dynamically:

const items = [
  {
    id: "1",
    name: "Item 1",
    isChecked: true,
    children: []
  },
  {
    id: "3",
    name: "Item 3",
    isChecked: false,
    children: [
      {
        id: "3.1",
        name: "Child 1",
        isChecked: false,
        children: [
          {
            id: "3.1.1",
            name: "Grandchild 1",
            isChecked: true,
            children: []
          },
          {
            id: "3.1.2",
            name: "Grandchild 2",
            isChecked: true,
            children: []
          }
        ]
      },
      {
        id: "3.2",
        name: "Child 2",
        isChecked: false,
        children: []
      }
    ]
  }
]

我很难弄清楚如何从深层嵌套的组件中更新顶级状态,因为它仅了解"自身,而不是整个数据结构.

I have a problem figuring out how to update the top level state from within a deeply nested component, because it only "knows" about itself, not the entire data structure.

class App extends React.Component {
  state = {
    items
  };

  recursivelyRenderItems(items) {
    return (
      <ul>
        {items.map(item => (
        <li key={item.id}>
          {item.name}
          <input type="checkbox" checked={item.isChecked} onChange={(event) => {
            // TODO: Update the item's checked status
          }} />
          {this.recursivelyRenderItems(item.children)}
        </li>
    ))}
      </ul>

    )
  }

  render() {
    return (
      <div>
        {this.recursivelyRenderItems(this.state.items)}
      </div>
    );
  }
}

请问我该如何实现?

推荐答案

如何解决:

创建一个带有两个参数的 updateState 函数: id newState .由于您的 ids 已经告诉您要更新的项目: 3、3.1、3.1.1 ,因此您可以从任何递归项目中使用调用更新函数您要修改的项目的> id .用点将 id 分开,然后递归扔出您的物品以找出合适的物品.

Create an updateState function that takes two args: id and newState. Since your ids already tell you what item you are updating: 3, 3.1, 3.1.1, you can from any of the recursive items call your update function with the id of the item you want to modify. Split the id by dots and go throw your items recursively to find out the right one.

例如,从递归呈现的项目 3.1.1 中,可以像这样调用 updateState : updateState('3.1.1',newState).

For example from the recursive rendered item 3.1.1, can call updateState like this: updateState('3.1.1', newState).

import React from "react";
import { render } from "react-dom";
import items from "./items";

class App extends React.Component {
  state = {
    items
  };

  updateState = item => {
    const idArray = item.id.split(".");
    const { items } = this.state;

    const findItem = (index, children) => {
      const id = idArray.slice(0, index).join(".");
      const foundItem = children.find(item => item.id === id);
      if (index === idArray.length) {
        foundItem.isChecked = !item.isChecked;
        this.setState(items);
        return;
      } else {
        findItem(index + 1, foundItem.children);
      }
    };

    findItem(1, items);
  };

  recursivelyRenderItems(items) {
    return (
      <ul>
        {items.map(item => (
          <li key={item.id}>
            {item.name}
            <input
              type="checkbox"
              checked={item.isChecked}
              onChange={event => this.updateState(item)}
            />
            {this.recursivelyRenderItems(item.children)}
          </li>
        ))}
      </ul>
    );
  }

  render() {
    return <div>{this.recursivelyRenderItems(this.state.items)}</div>;
  }
}

render(<App />, document.getElementById("root"));

工作示例.

这篇关于从React.js中的递归渲染组件更新状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆