javascript - 操作多个子组件的状态

标签 javascript html reactjs components state

我不确定是否最好在单个子组件或父组件中保留状态。

我有一个父组件,它将容纳一个需要能够按需复制的子组件。

我有几个问题:

  • 我在哪里存储单个组件的状态是在组件本身还是在父组件中?

  • 如果它在子组件中,我如何告诉父组件更新其他子组件。

  • 如果它在父级中,如何将函数传递给子级以更新 ITS 状态而不是父级状态?

  • 如何访问每个组件状态并告诉它根据另一个子状态的变化进行更改?

目前,我正在将一个新的“卡”组件推送到一个数组中,该数组跟踪我需要在“板”上渲染的所有组件。

我无法概念化管理一切状态以及如何访问每个子项的最佳方法。他们有个人身份证吗?我怎样才能改变他们所有的状态。

  • -------------------- 董事会 -------------------------- *
    import React from "react";
    import Card from "./Card";

    export default class Board extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          cards: [<Card />]
        };
      }

      componentDidMount() {}

      createCard() {
        this.state.cards.push(<Card />);
        this.forceUpdate();
      }

      render() {
        return (
          <div id="Board">
            <button onClick={() => this.createCard()}>Create Card</button>
            {this.state.cards.map(card => (
              <Card />
            ))}
          </div>
        );
      }
    }
  • -------------------------- 卡 -------------------- ---------- *
 export default class Card extends React.Component {
   constructor(props) {
     super(props);
     this.state = {
       active: false
     };
   }

   cardClick = () => {
     this.setState({
       active: !this.state.active
     });
   };

   render(cardClick) {
     return (
       <div>
         {this.state.active ? (
           <div
             className="activeCard"
             id="card"
             onClick={() => this.cardClick()}
           >
             Active
           </div>
         ) : (
           <div
             className="inactiveCard"
             id="card"
             onClick={() => this.cardClick()}
           >
             Inactive
           </div>
         )}
       </div>
     );
   }
 } ```



最佳答案

好吧,让我们从头开始。我想您有一些想要呈现为 <Card /> 的数据,每个数据项一个。您保存的不是状态中的组件,而是数据。例如:

this.state = {
  data: [
    {value: 'Cat 1'},
    {value: 'Cat 2'},
    {value: 'Cat 3'}
  ] 
} 

在这种情况下,父级保存数据是正确的。然而,lifting the state up (React docs link)的整个概念并不是那么难。大多数情况下,这是一个问题:是否有多个组件关心/依赖于同一状态?如果答案是肯定的,通常 parent 应该持有它。让每张卡保持其自己的事件状态是正确的。然而, parent 也可以这样做。那么我们就这样做吧:

Board.js

import React from 'react';
import {Card} from './Card';    

class Board extends React.Component{
    state = {
      data: [
        {value: 'Cat 1'},
        {value: 'Cat 2'},
        {value: 'Cat 3'}
      ],
      activeCard: null, 
    }
    cardClick = id => {
       this.setState({ activeCard: id })
    }
    addCard = () => {
      const newCard = { value: 'Some val here' };
      this.setState({ data: [...this.state.data, newCard] });
    }
    render(){
      return(
        <div id="Board">
          <button onClick={this.addCard}>Add a card</button>
          {this.state.data.map((item, index) => 
            <Card key={index} 
              value={item.value} 
              active={this.state.activeCard === index}
              cardClick={this.cardClick}
              index={index}
            />
           )}
         </div>
       )
    }
}

export default Board;

通过这样做,我们的 parent 可以管理一切。并不是说这是唯一正确的方法,但这让我们拥有 Card组件作为“哑”功能组件。请小心 - 这种特定方法依赖于永不改变顺序的数据,因为它依赖于 .map索引,从 0 到数据长度 - 1。

Card.js

import React from 'react';

const Card = props => (
    <div
        className={props.active ? 'activeCard' : 'inactiveCard'}
        onClick={() => props.cardClick(props.index)}
    >
        Active
    </div>
);

export { Card };

您发布的内容和我所做的内容之间存在一些关键差异。

1) 您正在使用相同的 id="card" 映射卡片。这很糟糕,id 应该是唯一的。另外,除非您确实需要它,否则可以省略它。

2) 我正在切换 className基于事件卡的索引。如果当前卡(假设为 2)也是事件卡,则它将具有 activeCard类(class)名称。

3) 最后,我将一个函数传递给子级来更新父级状态。通过这样做,我将状态包含在父级中,并且每次更新它时,它也会反射(reflect)在子级中。这并不是说您为卡片使用基于类的组件的方法是错误的,但我认为这更简单。

4)只是把它扔在那里,WAI-ARIA不太同意 div 有 onClick事件。为了使互联网成为一个很酷、易于访问的地方,您可以将 role="button"在 div 上,表示它是一个按钮。这还要求它是可聚焦的,以及键盘事件监听器,在这种情况下,您最好只使用 <button>元素是否可点击。

回答您的其他问题:

  • 父级自动将所有状态更改传播给所有关心它的子级

  • 所有子组件都独立于父组件,例如,如果它们有自己的状态,则父组件不关心。只有当它们共享状态和状态更新函数时,这才变得相关,因此只有当您专门将此类函数传递给子级时

  • 如果 children 共享一个状态,那么它应该被提升,这在链接的文档中有解释!

编辑:对于给定的示例,我假设您一次只需要一张事件卡。如果情况并非如此,要么让每张卡保持其事件状态,就像基诺·克莱顿建议的那样,要么更改 activeCard放入数组中,根据事件卡数组检查每张卡的索引

关于javascript - 操作多个子组件的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54395209/

相关文章:

javascript - javascript 代码应该始终加载在 html 文档的头部吗?

javascript - 通过控制台捕获网页http请求

javascript - 通过gapi.signin2.render按钮的Google OAuth未在React应用程序中触发回调

javascript - 关闭弹出窗口后刷新父窗口

javascript - 为什么我的 xml 出现未定义错误?

javascript - Jquery 移动端按住并单击

javascript - HighChart - 可以在标题和副标题之间画线

javascript - 在 Javascript 中更改 CSS 显示样式

javascript - Material 用户界面 : how to change fontSize in Lists?

javascript - Shadow DOM 中的 React 组件时单击事件不会触发