元素共享状态

时间:2019-07-02 16:04:52

标签: javascript reactjs material-ui

我正在尝试使用React使用JS编写一个初级项目(什么都不做,只是为了获得一些经验)。因此-我有点新鲜...我要去那个通用的“ notes app”。

但是从服务器获取便笺并渲染它们(使用@ material-ui Card元素)面临一个问题:所有便笺处于共享状态:单击某人的“展开”图标会使所有卡片展开(但仅显示数据在一个点击)。再次单击(在之前单击的那一项上)将全部关闭

这是我第一次使用'useState'钩子和@ material-ui。 我有一些关于React的经验,包括类和无状态组件。但是以前没有遇到过。

这是Notes组件,它呈现与保存的一样多的Note元素。

  parseNotes = (data) => {
    const toBeNotes = [];
    for (let key in data) {
      toBeNotes.push(data[key]);
    }
    const aux = toBeNotes.map((note, i) => {
      return (
        <Note key={i} {...note} />
      )
    })
    this.setState({ notes: aux });
  }

  render() {
    return (
      <div className="notes">{...this.state.notes}</div>
    )

}

这是Note组件的代码:

const [open, setOpen] = useState(false);
  function openHandler() {
    setOpen(!open);
  }
  return (
    <Card raised className="note">
      <CardHeader
        title={props.title}
        subheader={`Due at: ${props.date}, at ${props.time}`}
      />
      <CardActions>
        <IconButton>
          <ExpandMoreIcon
            onClick={openHandler}
          />
        </IconButton>
      </CardActions>
      <Collapse in={open}>
        <CardContent>
         <h6>{props.body}</h6>
        </CardContent>
      </Collapse>
    </Card>
  )

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

如果将Note更改为以下内容,会发生什么情况:

export const Note = ({date, time, title, body}) => {
  const [open, setOpen] = useState(false);
  return (
    <Card raised className="note">
      <CardHeader
        title={title}
        subheader={`Due at: ${date}, at ${time}`}
      />
      <CardActions>
        <IconButton>
          <ExpandMoreIcon
            onClick={() => setOpen(!open)}
          />
        </IconButton>
      </CardActions>
      <Collapse in={open}>
        <CardContent>
         <h6>{body}</h6>
        </CardContent>
      </Collapse>
    </Card>
  )
};

(侧边栏:您可以将open传递到ExpandMoreIcon中,以便可以更改图标以反映所反映的动作)

在这种情况下,open应该只与您正在使用的Card相关,并且不会/不应该影响显示屏中的其他Note。如果您一次需要处理一个打开/关闭操作,则必须从一个较高的组件向下传递一种方法,该方法可以跟踪每个组件的打开/关闭状态(可能基于其索引)(哪个,BTW,您永远不要使用作为您的key。只需为每个Note提供自己的唯一标识符,然后将其用作您的key。)

答案 1 :(得分:0)

每个组件都独立于另一个组件工作。因此2个音符的“打开”状态是不同的,并且仅在内部绑定到它们的音符。因此,它不会影响其他注释。错误原因必须不同。您必须提供这2个文件的完整代码。

为确认起见,我编写了一段代码,其中制作了一个最初显示红色的ColoredButton组件,当我单击它时,它切换为黑色,再次单击时,它切换为红色,因此然后,在我的App Component(直接在index.js中呈现)中使用此组件10次,并注意到每个ColoredComponent的行为都独立于另一个组件。

ColorButton.js

const ColoredButton = props => {
  const redHex = "#f00";
  const blackHex = "#000";
  const [color, setColor] = useState(redHex);
  return (
    <React.Fragment>
      <button
        onClick={event => {
          event.preventDefault();
          if (color === redHex) {
            setColor(blackHex);
          } else {
            setColor(redHex);
          }
        }}
        style={{ color: `${color}` }}
      >
        Toggle My Color
      </button>
    </React.Fragment>
  );
};

export default ColoredButton;

index.js

import React from "react";
import ReactDOM from "react-dom";

import ColoredButton from "./ColoredButton";

import "./styles.css";

function App() {
  let buttons10 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  return (
    <React.Fragment>
      {buttons10.map(buttonNo => (
        <ColoredButton key={buttonNo} />
      ))}
    </React.Fragment>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

您可以在CodeSandbox上尝试使用此代码。

如果此示例代码不能帮助您解决问题,请提供这两个文件的完整代码。