如何将数据传递到{props.children}

时间:2020-06-11 09:29:30

标签: javascript reactjs react-hooks

关于我的后续问题,请点击此处:How to pass data from child to parent component using react hooks 我还有另一个问题。 下面是组件结构

export const Parent: React.FC<Props> = (props) => {
const [disabled, setDisabled] = React.useState(false);
const createContent = (): JSX.Element => {
  return (
    <Authorization>
    {<ErrorPanel message={errorMessage} setDisabled={setDisabled}/>}
    <MyChildComponent/>
    </<Authorization>
  );
}

return (
   <Button onClick={onSubmit} disabled={disabled}>My Button</Button>
   {createContent()}
 );
};

const Authorization: React.FC<Props> = (props) => {
const [disabled, setDisabled] = React.useState(false);
const render = (errorMessage : JSX.Element): JSX.Element => {
    return (
      <>
      {<ErrorPanel message={errorMessage} setDisabled={setDisabled}/>}
      </>
    );
  };

return (
    <>
    <PageLoader
      queryResult={apiQuery}
      renderPage={render}
    />
    {props.children}
    </>
  );
};

如何将禁用状态值从“授权”组件传递给我的孩子,该孩子由以下人员调用 {props.children} 我尝试了React.cloneElement和React.createContext,但无法将值禁用为MyChildComponent。一旦通过Authorization组件中的true设置了errorMessage,我可以看到禁用的值为ErrorPanel。 我是否需要在授权组件中使用React.useEffect

我在这里想念什么?

2 个答案:

答案 0 :(得分:1)

您可以使用React.cloneElementReact.Children.mapdisabled prop传递给直接子组件

const Authorization: React.FC<Props> = (props) => {
    const [disabled, setDisabled] = React.useState(false);
    const render = (errorMessage : JSX.Element): JSX.Element => {
        return (
          <>
          {<ErrorPanel message={errorMessage} setDisabled={setDisabled}/>}
          </>
        );
      };

    return (
        <>
        <PageLoader
          queryResult={apiQuery}
          renderPage={render}
        />
        {React.Children.map(props.children, child => {
            return React.cloneElement(child, { disabled })
         })}
        </>
      );
};

更新:

由于您希望将父状态更新为该状态,因此应该存储该状态和父状态并在其自身进行更新,而不是将状态也存储在子组件中。

export const Parent: React.FC<Props> = (props) => {
const [disabled, setDisabled] = React.useState(false);
const createContent = (): JSX.Element => {
  return (
    <Authorization setDisabled={setDisabled}>
    {<ErrorPanel message={errorMessage} disabled={disabled} setDisabled={setDisabled}/>}
    <MyChildComponent disabled={disabled}/>
    </<Authorization>
  );
}

return (
   <Button onClick={onSubmit} disabled={disabled}>My Button</Button>
   {createContent()}
 );
};

const Authorization: React.FC<Props> = (props) => {
const render = (errorMessage : JSX.Element): JSX.Element => {
    return (
      <>
      {<ErrorPanel message={errorMessage} disabled={props.disabled} setDisabled={props.setDisabled}/>}
      </>
    );
  };

return (
    <>
    <PageLoader
      queryResult={apiQuery}
      renderPage={render}
    />
    {props.children}
    </>
  );
};

答案 1 :(得分:1)

您需要将React.Children API与React.cloneElement一起使用:

const Authorization = ({ children }) => {
  const [disabled, setDisabled] = React.useState(false);

  const render = (errorMessage) => {
    return (
      <>{<ErrorPanel message={errorMessage} setDisabled={setDisabled} />}</>
    );
  };

  return (
    <>
      <PageLoader queryResult={apiQuery} renderPage={render} />
      {React.Children.map(children, (child) =>
        React.cloneElement(child, { disabled })
      )}
    </>
  );
};


// | 
// v
// It will inject `disabled` prop to every component's child:
<>
  <ErrorPanel
    disabled={disabled}
    message={errorMessage}
    setDisabled={setDisabled}
  />
  <MyChildComponent disabled={disabled} />
</>