javascript - 如何在同一组件中使用 React useContext 来显示上下文中的数据

标签 javascript reactjs react-hooks

我正在创建一个 react 向导组件,并希望使用上下文在父级和子级之间传递数据

因此,我创建了一个向导、上下文、提供程序和自定义 Hook ,但问题是,如果我尝试在向导组件上使用上下文,它不会显示正确的信息

(参见 https://codesandbox.io/embed/wizardwitcontext-rfpui )

如何做到这一点,以便我可以依赖向导本身上下文中的数据,以便我可以将登录转移到自定义 Hook ?

useWizard.js:

import React, { useContext, useEffect } from "react";
import { WizardContext } from "./WizardContext";

const useWizard = () => {
  const [state, setState] = useContext(WizardContext);

  function setMaxSteps(maxSteps) {
    setState(state => ({ ...state, maxSteps }));
  }
  function moveToStep(index) {
    if (state.maxSteps && state.maxSteps > index) {
      setState({ ...state, currentStep: index });
      return index;
    }
    return state.currentStep;
  }

  function back() {
    if (state.maxSteps) {
      if (state.currentStep > 0) {
        setState({ ...state, currentStep: state.currentStep - 1 });
        window.scrollTo(0, 0);
      }
    }
  }

  //move back a step
  function next() {
    if (state.currentStep < state.maxSteps) {
      setState({ ...state, currentStep: state.currentStep + 1 });
      window.scrollTo(0, 0);
    }
  }

  return {
    setMaxSteps,
    moveToStep,
    back,
    next,
    maxSteps: state.maxSteps,
    currentStep: state.currentStep,
    state
  };
};

export default useWizard;

向导.jsx:

const { state, currentStep, back, next, maxSteps, setMaxSteps } = useWizard();

return (
    <div className="wizard">
      <WizardProvider
        maxSteps={React.Children.count(props.children)}
        currentStep={0}
      >
        {/* <div className="wizard__upper">
          <ProgressIndicator currentIndex={selected} onChange={onClick}>
            {steps}
          </ProgressIndicator>

          <Button id="wizardCloseBtn" kind="ghost" onClick={onClose}>
            <Icon icon={iconHeaderClose} />
          </Button>
        </div> */}
        <div className="wizard__separator" />
        <div className="wizard__content">
          {`in wizard: cur=${currentStep}, max=${maxSteps}`}
          {/* {getContentAt(0)} */}
          {stepContentWithProps}
        </div>

        {/* <div className="wizard__buttons">
          {showBack && (
            <Link id="back" onClick={back}>
              back
            </Link>
          )}
          {showNext && (
            <button id="next" onClick={next} kind="secondary">
              Next Step
            </button>
          )}
        </div> */}
      </WizardProvider>
    </div>
  );

第二步:

import React, { useState, useContext, useEffect } from "react";
import useWizard from "./useWizard";

function Step2(props) {
  const {
    currentStep,
    moveToStep,
    maxSteps,
    setMaxSteps,
    next,
    prev
  } = useWizard();

  return (
    <div>
      <p>Step 2</p>
      {`in step2 (inner child of wizard): cur=${currentStep} see that cur !== cur from wizard above`}
      <br />
      <button onClick={() => moveToStep(1)}>
        Click me to change current step
      </button>
    </div>
  );
}

export default Step2;

最终结果是:

in wizard: cur=undefined, max=undefined
p1

in index.js: cur=undefined
Step 2

in step2 (inner child of wizard): cur=0 see that cur !== cur from wizard above


最佳答案

您在与Context.Provider同一级别中调用useContext:

function Wizard(props) {
  // useWizard calls useContext
  const { state, currentStep, back, next, maxSteps, setMaxSteps } = useWizard();

  return (
    <div className="wizard">
      <WizardProvider
        maxSteps={React.Children.count(props.children)}
        currentStep={0}
      >
        <div className="wizard__content">
          {`in wizard: cur=${currentStep}, max=${maxSteps}`}
        </div>
      </WizardProvider>
    </div>
  );
}

您需要更改结构并在 Provider 子级中调用 useContext

function Wizard(props) {
  // useWizard calls useContext
  const { state, currentStep, back, next, maxSteps, setMaxSteps } = useWizard();

  return (
//      v You trying to get Provider's value here
    <div className="wizard">
      <WizardProvider
        maxSteps={React.Children.count(props.children)}
        currentStep={0}
      >
//      v useContext available within the children
        <ComponentA />
        <ComponentB />
      </WizardProvider>
    </div>
  );
}

引用Context API , useContext .

关于javascript - 如何在同一组件中使用 React useContext 来显示上下文中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58152818/

相关文章:

javascript - 我如何获得 fullcalendar v.4.2.0 实例?

javascript - 我可以在其中附加书面内容的框

javascript - 将对象作为参数传递到 Angular ui-router

javascript - 有没有办法改变 React 中输入的类型?

javascript - 站点自动重定向

javascript - 设置ReactJS会导致额外的div,新组件?

javascript - 条件渲染标记 (JSX) 与 CSS `display: none` - 哪个更好?

reactjs - useState 更新状态值,但将旧值作为参数传递给函数

javascript - 使用 useState Hook react js

reactjs - react 钩子(Hook)重复 react 包