Reactjs子组件

发布时间:2020-07-07 17:18

我对反应的层次结构有疑问。

我的Main.js有2篇文章,如下:

        <article className="angel__flow">
          {steps.map((step, index) => {
            if (procedures[step]){
              return (
                <Flow
                  key={`${index}-${step}`}
                  index={index}
                  opened={currentStepIndex === index}
                  procedure={procedures[step]}
                />
              );
            } else return "";
          })}
        </article>
        <article className="angel__steps">
          {steps.map((step, index) => {
            if (procedures[step]){
              return (
                <Steps
                  key={`${index}-${step}`}
                  index={index}
                  opened={currentStepIndex === index}
                  procedure={procedures[step]}
                  commandSender={sendViewerMessage}
                />
              );
            } else return "";
          })}
        </article>

每篇文章都有一张地图,对于每一项,它都调用一个函数。第一个调用Flow函数,第二个调用Steps函数。

我的流程功能如下:

function Flow({ index, opened, procedure }) {

  const { t, i18n } = useTranslation();
  const [show, setShow] = useState(false);

  useEffect(()=>{
    setShow(opened)
  },[opened])

  return (
    <a onClick={() => setShow(!show)} className={`angel__flow__button ${show ? "active" : ""}`}>     
      {t(procedure.title[i18n.language])}
      <span class="angel__flow__button__number">{index+1}</span>  
    </a>
  );
}

我的Steps函数如下:

function Steps({ index, opened, procedure, commandSender }) {

  const { i18n } = useTranslation();
  const [selected, setSelected] = useState([]);

  function clickHandler(command, index, key, procedure) {
     if (!isSelected(key)) commandSender(`${command}|${index}|${procedure.id}|${key}`)

    if (isSelected(key)) setSelected(selected.filter(s => s !== key))
    else setSelected([...selected, (key)])
  }

  function isSelected(key) {
    return selected.includes(key);
  }

  return (
    <>
      { opened && (
        <>
          {procedure.guide &&
            map(procedure.guide, (value, key) => (
              <a
                key={key}
                className={`angel__steps__button blue ${isSelected(key) ? "active" : ""}`}
                onClick={() => clickHandler('GUIDE', index, key, procedure)}
              >
                {value[i18n.language]}
              </a>
            ))
          }
          <hr />
          {procedure.error &&
            map(procedure.error, (value, key) => (
              <a
                key={key}
                className={`angel__steps__button red ${isSelected(key) ? "active" : ""}`}
                onClick={() => clickHandler('ERROR', index, key, procedure)}
              >
                {value[i18n.language]}
              </a>
            ))
          }
          {procedure.success &&
            map(procedure.success, (value, key) => (
              <a
                key={key}
                className={`angel__steps__button green ${isSelected(key) ? "active" : ""}`}
                onClick={() => clickHandler('SUCCESS', index, key, procedure)}
              >
                {value[i18n.language]}
              </a>
            ))
          }
        </>
      )}
    </>
  );
}

我需要做的是:当我在Flow函数中单击A标签时,它必须打开该标签的Steps。

所以,我不知道该怎么办。也许将一个标记发送回我的Main函数,该标志说我单击了该标记,因此,我的Steps函数将打开该标记。 你们可以帮我吗?

回答1

将点击处理程序传递到Flow中的Main.js

<Flow setCurrentStepHandler={(i) => this.setState({currentStepIndex: this.state.currentStepIndex === i ? null : i})}/>

Flow中:

<a onClick={() => {
  setShow(!show)
  setCurrentStepHandler(index)
}}

这样,当currentStepIndex更新时,它将作为道具传递给<Steps .../>